diff --git a/base/aaa/role.go b/base/aaa/role.go
index 52abfc49..6c13f06b 100644
--- a/base/aaa/role.go
+++ b/base/aaa/role.go
@@ -1,39 +1,29 @@
package aaa
import (
+ "path"
+ "strings"
+
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/mdb"
kit "shylinux.com/x/toolkits"
)
-func _role_list(m *ice.Message, userrole string) {
- m.Richs(ROLE, nil, kit.Select(mdb.FOREACH, userrole), func(key string, value ice.Map) {
- kit.Fetch(value[BLACK], func(k string, v ice.Any) {
- m.Push(ROLE, kit.Value(value, mdb.NAME))
- m.Push(mdb.ZONE, BLACK)
- m.Push(mdb.KEY, k)
- })
- kit.Fetch(value[WHITE], func(k string, v ice.Any) {
- m.Push(ROLE, kit.Value(value, mdb.NAME))
- m.Push(mdb.ZONE, WHITE)
- m.Push(mdb.KEY, k)
- })
- })
-}
func _role_chain(arg ...string) string {
- return kit.ReplaceAll(kit.ReplaceAll(kit.Keys(arg), ice.PS, ice.PT), "..", ".")
+ key := path.Join(strings.ReplaceAll(kit.Keys(arg), ice.PT, ice.PS))
+ return strings.TrimPrefix(strings.TrimSuffix(strings.ReplaceAll(key, ice.PS, ice.PT), ice.PT), ice.PT)
}
func _role_black(m *ice.Message, userrole, chain string) {
- m.Richs(ROLE, nil, userrole, func(key string, value ice.Map) {
- list := value[BLACK].(ice.Map)
+ mdb.HashSelectUpdate(m, userrole, func(value ice.Map) {
m.Log_INSERT(ROLE, userrole, BLACK, chain)
+ list := value[BLACK].(ice.Map)
list[chain] = true
})
}
func _role_white(m *ice.Message, userrole, chain string) {
- m.Richs(ROLE, nil, userrole, func(key string, value ice.Map) {
- list := value[WHITE].(ice.Map)
+ mdb.HashSelectUpdate(m, userrole, func(value ice.Map) {
m.Log_INSERT(ROLE, userrole, WHITE, chain)
+ list := value[WHITE].(ice.Map)
list[chain] = true
})
}
@@ -42,7 +32,7 @@ func _role_right(m *ice.Message, userrole string, keys ...string) (ok bool) {
return true // 超级权限
}
- m.Richs(ROLE, nil, kit.Select(VOID, userrole), func(key string, value ice.Map) {
+ mdb.HashSelectDetail(m, kit.Select(VOID, userrole), func(value ice.Map) {
ok = true
list := value[BLACK].(ice.Map)
for i := 0; i < len(keys); i++ {
@@ -73,9 +63,20 @@ func _role_right(m *ice.Message, userrole string, keys ...string) (ok bool) {
})
return ok
}
-
-func RoleRight(m *ice.Message, userrole string, keys ...string) bool {
- return _role_right(m, userrole, kit.Split(kit.Keys(keys), ice.PT)...)
+func _role_list(m *ice.Message, userrole string) *ice.Message {
+ mdb.HashSelectDetail(m, kit.Select(VOID, userrole), func(value ice.Map) {
+ kit.Fetch(value[BLACK], func(k string, v ice.Any) {
+ m.Push(ROLE, kit.Value(value, mdb.NAME))
+ m.Push(mdb.ZONE, BLACK)
+ m.Push(mdb.KEY, k)
+ })
+ kit.Fetch(value[WHITE], func(k string, v ice.Any) {
+ m.Push(ROLE, kit.Value(value, mdb.NAME))
+ m.Push(mdb.ZONE, WHITE)
+ m.Push(mdb.KEY, k)
+ })
+ })
+ return m
}
const (
@@ -91,10 +92,8 @@ const (
const ROLE = "role"
func init() {
- Index.Merge(&ice.Context{Configs: ice.Configs{
- ROLE: {Name: ROLE, Help: "角色", Value: kit.Data(mdb.SHORT, mdb.NAME)},
- }, Commands: ice.Commands{
- ROLE: {Name: "role role auto insert", Help: "角色", Actions: ice.Actions{
+ Index.MergeCommands(ice.Commands{
+ ROLE: {Name: "role role auto insert", Help: "角色", Actions: ice.MergeAction(ice.Actions{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
m.Rich(ROLE, nil, kit.Dict(mdb.NAME, TECH, BLACK, kit.Dict(), WHITE, kit.Dict()))
m.Rich(ROLE, nil, kit.Dict(mdb.NAME, VOID, WHITE, kit.Dict(), BLACK, kit.Dict()))
@@ -105,17 +104,17 @@ func init() {
m.Cmd(ROLE, WHITE, VOID, ice.USR_LOCAL_GO)
}},
mdb.INSERT: {Name: "insert role=void,tech zone=white,black key=", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
- m.Richs(ROLE, nil, m.Option(ROLE), func(key string, value ice.Map) {
+ mdb.HashSelectUpdate(m, m.Option(ROLE), func(key string, value ice.Map) {
m.Log_INSERT(ROLE, m.Option(ROLE), m.Option(mdb.ZONE), m.Option(mdb.KEY))
list := value[m.Option(mdb.ZONE)].(ice.Map)
- list[m.Option(mdb.KEY)] = true
+ list[_role_chain(m.Option(mdb.KEY))] = true
})
}},
mdb.DELETE: {Name: "delete", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
- m.Richs(ROLE, nil, m.Option(ROLE), func(key string, value ice.Map) {
+ mdb.HashSelectUpdate(m, m.Option(ROLE), func(key string, value ice.Map) {
m.Log_DELETE(ROLE, m.Option(ROLE), m.Option(mdb.ZONE), m.Option(mdb.KEY))
list := value[m.Option(mdb.ZONE)].(ice.Map)
- delete(list, m.Option(mdb.KEY))
+ delete(list, _role_chain(m.Option(mdb.KEY)))
})
}},
@@ -130,9 +129,12 @@ func init() {
m.Echo(ice.OK)
}
}},
- }, Hand: func(m *ice.Message, arg ...string) {
- _role_list(m, kit.Select("", arg, 0))
- m.PushAction(mdb.DELETE)
+ }, mdb.HashAction(mdb.SHORT, mdb.NAME)), Hand: func(m *ice.Message, arg ...string) {
+ _role_list(m, kit.Select("", arg, 0)).PushAction(mdb.DELETE)
}},
- }})
+ })
+}
+
+func RoleRight(m *ice.Message, userrole string, arg ...string) bool {
+ return m.Cmdx(ROLE, RIGHT, userrole, arg) == ice.OK
}
diff --git a/base/aaa/sess.go b/base/aaa/sess.go
index e5452dc4..bc6bc866 100644
--- a/base/aaa/sess.go
+++ b/base/aaa/sess.go
@@ -4,54 +4,44 @@ import (
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/mdb"
kit "shylinux.com/x/toolkits"
+ "shylinux.com/x/toolkits/logs"
)
-func _sess_check(m *ice.Message, sessid string) bool {
+func _sess_check(m *ice.Message, sessid string) {
m.Option(ice.MSG_USERROLE, VOID)
m.Option(ice.MSG_USERNAME, "")
m.Option(ice.MSG_USERNICK, "")
if sessid == "" {
- return false
+ return
}
- m.Richs(SESS, nil, sessid, func(value ice.Map) {
- if value = kit.GetMeta(value); m.Warn(kit.Time(kit.Format(value[mdb.TIME])) < kit.Time(m.Time()), ice.ErrNotValid) {
+ _source := logs.FileLineMeta(logs.FileLine(-1, 3))
+ mdb.HashSelectDetail(m, sessid, func(value ice.Map) {
+ if m.Warn(kit.Time(kit.Format(value[mdb.TIME])) < kit.Time(m.Time()), ice.ErrNotValid, sessid) {
return // 会话超时
}
- if m.Richs(USER, nil, value[USERNAME], func(value ice.Map) {
- m.Log_AUTH(
- USERROLE, m.Option(ice.MSG_USERROLE, value[USERROLE]),
- USERNAME, m.Option(ice.MSG_USERNAME, value[USERNAME]),
- USERNICK, m.Option(ice.MSG_USERNICK, value[USERNICK]),
- )
- }) == nil {
- m.Log_AUTH(
- USERROLE, m.Option(ice.MSG_USERROLE, value[USERROLE]),
- USERNAME, m.Option(ice.MSG_USERNAME, value[USERNAME]),
- USERNICK, m.Option(ice.MSG_USERNICK, value[USERNICK]),
- )
- }
+ m.Log_AUTH(
+ USERROLE, m.Option(ice.MSG_USERROLE, value[USERROLE]),
+ USERNAME, m.Option(ice.MSG_USERNAME, value[USERNAME]),
+ USERNICK, m.Option(ice.MSG_USERNICK, value[USERNICK]),
+ _source,
+ )
})
- return m.Option(ice.MSG_USERNAME) != ""
}
func _sess_create(m *ice.Message, username string) string {
if username == "" {
return ""
}
-
- h := m.Cmdx(mdb.INSERT, SESS, "", mdb.HASH, mdb.TIME, m.Time(m.Conf(SESS, kit.Keym(mdb.EXPIRE))),
- USERROLE, UserRole(m, username), USERNAME, username, USERNICK, UserNick(m, username),
- IP, m.Option(ice.MSG_USERIP), UA, m.Option(ice.MSG_USERUA),
- )
- m.Event(SESS_CREATE, SESS, h, USERNAME, username)
- return h
-}
-
-func SessCreate(m *ice.Message, username string) string {
- return m.Option(ice.MSG_SESSID, _sess_create(m, username))
-}
-func SessCheck(m *ice.Message, sessid string) bool {
- return _sess_check(m, sessid)
+ msg := m.Cmd(USER, username)
+ if msg.Length() > 0 {
+ h := mdb.HashCreate(m, msg.AppendSimple(USERROLE, USERNAME, USERNICK), IP, m.Option(ice.MSG_USERIP), UA, m.Option(ice.MSG_USERUA)).Result()
+ m.Event(SESS_CREATE, SESS, h, USERNAME, username)
+ return h
+ } else {
+ h := mdb.HashCreate(m, m.OptionSimple(USERROLE, USERNAME, USERNICK), IP, m.Option(ice.MSG_USERIP), UA, m.Option(ice.MSG_USERUA)).Result()
+ m.Event(SESS_CREATE, SESS, h, USERNAME, username)
+ return h
+ }
}
const (
@@ -59,10 +49,11 @@ const (
UA = "ua"
)
const (
+ CHECK = "check"
GRANT = "grant"
LOGIN = "login"
LOGOUT = "logout"
- EXPIRE = "expire"
+ SESSID = "sessid"
)
const (
SESS_CREATE = "sess.create"
@@ -70,15 +61,21 @@ const (
const SESS = "sess"
func init() {
- Index.Merge(&ice.Context{Configs: ice.Configs{
- SESS: {Name: SESS, Help: "会话", Value: kit.Data(
- mdb.SHORT, "uniq", mdb.FIELD, "time,hash,userrole,username,usernick,ip,ua", mdb.EXPIRE, "720h",
- )},
- }, Commands: ice.Commands{
+ Index.MergeCommands(ice.Commands{
SESS: {Name: "sess hash auto prunes", Help: "会话", Actions: ice.MergeAction(ice.Actions{
- mdb.CREATE: {Name: "create username", Help: "创建"},
- }, mdb.HashAction()), Hand: func(m *ice.Message, arg ...string) {
- mdb.HashSelect(m, arg...)
- }},
- }})
+ mdb.CREATE: {Name: "create username", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
+ _sess_create(m, m.Option(USERNAME))
+ }},
+ CHECK: {Name: "check sessid", Help: "检查", Hand: func(m *ice.Message, arg ...string) {
+ _sess_check(m, m.Option(SESSID))
+ }},
+ }, mdb.HashAction(mdb.SHORT, mdb.UNIQ, mdb.FIELD, "time,hash,userrole,username,usernick,ip,ua", mdb.EXPIRE, "720h"))},
+ })
+}
+
+func SessCreate(m *ice.Message, username string) string {
+ return m.Option(ice.MSG_SESSID, m.Cmdx(SESS, mdb.CREATE, username))
+}
+func SessCheck(m *ice.Message, sessid string) bool {
+ return m.Cmdy(SESS, CHECK, sessid).Option(ice.MSG_USERNAME) != ""
}
diff --git a/base/aaa/totp.go b/base/aaa/totp.go
index ee67def5..429ce8cf 100644
--- a/base/aaa/totp.go
+++ b/base/aaa/totp.go
@@ -43,8 +43,6 @@ func _totp_get(key string, num int, per int64) string {
return kit.Format(kit.Format("%%0%dd", num), res%int64(math.Pow10(num)))
}
-func TOTP_GET(key string, num int, per int64) string { return _totp_get(key, num, per) }
-
const (
SECRET = "secret"
PERIOD = "period"
@@ -55,20 +53,15 @@ const (
const TOTP = "totp"
func init() {
- Index.Merge(&ice.Context{Configs: ice.Configs{
- TOTP: {Name: TOTP, Help: "令牌", Value: kit.Data(
- mdb.SHORT, mdb.NAME, mdb.FIELD, "time,name,secret,period,number", mdb.LINK, "otpauth://totp/%s?secret=%s",
- )},
- }, Commands: ice.Commands{
+ Index.MergeCommands(ice.Commands{
TOTP: {Name: "totp name auto create", Help: "令牌", Actions: ice.MergeAction(ice.Actions{
mdb.CREATE: {Name: "create name=hi secret period=30 number=6", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
if m.Option(SECRET) == "" { // 创建密钥
m.Option(SECRET, _totp_gen(kit.Int64(m.Option(PERIOD))))
}
-
- m.Cmd(mdb.INSERT, TOTP, "", mdb.HASH, m.OptionSimple(mdb.NAME, SECRET, PERIOD, NUMBER))
+ mdb.HashCreate(m, m.OptionSimple(mdb.NAME, SECRET, PERIOD, NUMBER))
}},
- }, mdb.HashAction()), Hand: func(m *ice.Message, arg ...string) {
+ }, mdb.HashAction(mdb.SHORT, mdb.NAME, mdb.FIELD, "time,name,secret,period,number", mdb.LINK, "otpauth://totp/%s?secret=%s")), Hand: func(m *ice.Message, arg ...string) {
mdb.HashSelect(m.Spawn(), arg...).Tables(func(value ice.Maps) {
if len(arg) > 0 {
m.OptionFields(mdb.DETAIL)
@@ -86,5 +79,7 @@ func init() {
}
})
}},
- }})
+ })
}
+
+func TOTP_GET(key string, num int, per int64) string { return _totp_get(key, num, per) }
diff --git a/base/aaa/user.go b/base/aaa/user.go
index 98968d0d..5350d5c4 100644
--- a/base/aaa/user.go
+++ b/base/aaa/user.go
@@ -4,95 +4,52 @@ import (
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/mdb"
kit "shylinux.com/x/toolkits"
+ "shylinux.com/x/toolkits/logs"
)
-func _user_exists(m *ice.Message, name string) bool {
- return m.Richs(USER, nil, name, nil) != nil
-}
-func _user_login(m *ice.Message, name, word string) (ok bool) {
- if !_user_exists(m, name) {
+func _user_login(m *ice.Message, name, word string) {
+ if m.Warn(name == "", ice.ErrNotValid, name) {
+ return
+ }
+ if !mdb.HashSelectDetail(m, name, nil) {
_user_create(m, VOID, name, word)
}
- m.Richs(USER, nil, name, func(key string, value ice.Map) {
- if ok = !m.Warn(word != "" && word != value[PASSWORD], ice.ErrNotRight); ok {
- m.Log_AUTH(
- USERROLE, m.Option(ice.MSG_USERROLE, value[USERROLE]),
- USERNAME, m.Option(ice.MSG_USERNAME, value[USERNAME]),
- USERNICK, m.Option(ice.MSG_USERNICK, value[USERNICK]),
- )
+ _source := logs.FileLineMeta(logs.FileLine(-1, 3))
+ mdb.HashSelectDetail(m, name, func(value ice.Map) {
+ if m.Warn(word != "" && word != kit.Format(kit.Value(value, kit.Keys(mdb.EXTRA, PASSWORD))), ice.ErrNotRight) {
+ return
}
+ m.Log_AUTH(
+ USERROLE, m.Option(ice.MSG_USERROLE, value[USERROLE]),
+ USERNAME, m.Option(ice.MSG_USERNAME, value[USERNAME]),
+ USERNICK, m.Option(ice.MSG_USERNICK, value[USERNICK]),
+ _source,
+ )
})
- return ok
}
-func _user_create(m *ice.Message, role, name, word string) {
- if name == "" {
+func _user_create(m *ice.Message, name, word string, arg ...string) {
+ if m.Warn(name == "", ice.ErrNotValid, name) {
return
}
if word == "" {
- if m.Richs(USER, nil, name, func(key string, value ice.Map) {
- word = kit.Format(value[PASSWORD])
- }) == nil {
- word = kit.Hashs()
- }
+ word = m.CmdAppend(USER, name, PASSWORD)
}
- m.Rich(USER, nil, kit.Dict(USERROLE, role, USERNAME, name, PASSWORD, word))
+ if word == "" {
+ word = kit.Hashs()
+ }
+ mdb.HashCreate(m, USERNAME, name, PASSWORD, word, arg)
m.Event(USER_CREATE, USER, name)
}
-func _user_search(m *ice.Message, name, text string) {
- m.Richs(USER, nil, mdb.FOREACH, func(key string, value ice.Map) {
- if value = kit.GetMeta(value); name == "" || name == value[USERNAME] {
- m.PushSearch(kit.SimpleKV("", value[USERROLE], value[USERNAME], value[USERNICK]), value)
- }
- })
-}
-
-func UserRoot(m *ice.Message, arg ...string) *ice.Message { // password username userrole
- username := m.Option(ice.MSG_USERNAME, kit.Select(ice.Info.UserName, arg, 1))
- userrole := m.Option(ice.MSG_USERROLE, kit.Select(ROOT, arg, 2))
- if len(arg) > 0 {
- _user_create(m, userrole, username, kit.Select("", arg, 0))
- ice.Info.UserName = username
- }
- return m
-}
-func UserRole(m *ice.Message, username ice.Any) (role string) {
- if role = VOID; username == ice.Info.UserName {
- return ROOT
- }
- if m.Richs(USER, nil, kit.Format(username), func(key string, value ice.Map) {
- role = kit.Format(kit.GetMeta(value)[USERROLE])
- }) == nil && kit.Format(username) == m.Option(ice.MSG_USERNAME) {
- return m.Option(ice.MSG_USERROLE)
- }
- return
-}
-func UserNick(m *ice.Message, username ice.Any) (nick string) {
- if m.Richs(USER, nil, kit.Format(username), func(key string, value ice.Map) {
- nick = kit.Format(kit.GetMeta(value)[USERNICK])
- }) == nil && kit.Format(username) == m.Option(ice.MSG_USERNAME) {
- return m.Option(ice.MSG_USERNICK)
- }
- return
-}
-func UserZone(m *ice.Message, username ice.Any) (zone string) {
- m.Richs(USER, nil, kit.Format(username), func(key string, value ice.Map) {
- zone = kit.Format(kit.GetMeta(value)[USERZONE])
- })
- return
-}
-func UserLogin(m *ice.Message, username, password string) bool {
- return _user_login(m, username, password)
-}
const (
+ BACKGROUND = "background"
+
AVATAR = "avatar"
GENDER = "gender"
MOBILE = "mobile"
EMAIL = "email"
- BACKGROUND = "background"
-
CITY = "city"
COUNTRY = "country"
LANGUAGE = "language"
@@ -114,24 +71,50 @@ const (
const USER = "user"
func init() {
- Index.Merge(&ice.Context{Configs: ice.Configs{
- USER: {Name: USER, Help: "用户", Value: kit.Data(
- mdb.SHORT, USERNAME, mdb.FIELD, "time,userrole,username,usernick,userzone",
- )},
- }, Commands: ice.Commands{
+ Index.MergeCommands(ice.Commands{
USER: {Name: "user username auto create", Help: "用户", Actions: ice.MergeAction(ice.Actions{
mdb.SEARCH: {Name: "search type name text", Help: "搜索", Hand: func(m *ice.Message, arg ...string) {
- if arg[0] == USER {
- _user_search(m, arg[1], kit.Select("", arg, 2))
- }
+ mdb.HashSelectSearch(m, arg)
}},
- mdb.CREATE: {Name: "create userrole=void,tech username password", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
- if !_user_exists(m, m.Option(USERNAME)) {
- _user_create(m, m.Option(USERROLE), m.Option(USERNAME), m.Option(PASSWORD))
- }
+ mdb.CREATE: {Name: "create username password userrole=void,tech", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
+ _user_create(m, m.Option(USERNAME), m.Option(PASSWORD), m.OptionSimple(USERROLE)...)
}},
- }, mdb.HashAction()), Hand: func(m *ice.Message, arg ...string) {
- mdb.HashSelect(m, arg...)
- }},
- }})
+ LOGIN: {Name: "login username password", Help: "登录", Hand: func(m *ice.Message, arg ...string) {
+ _user_login(m, m.Option(USERNAME), m.Option(PASSWORD))
+ }},
+ }, mdb.HashAction(mdb.SHORT, USERNAME, mdb.FIELD, "time,userrole,username,usernick,userzone"))},
+ })
+}
+
+func UserRoot(m *ice.Message, arg ...string) *ice.Message { // password username userrole
+ username := m.Option(ice.MSG_USERNAME, kit.Select(ice.Info.UserName, arg, 1))
+ userrole := m.Option(ice.MSG_USERROLE, kit.Select(ROOT, arg, 2))
+ if len(arg) > 0 {
+ m.Cmd(USER, mdb.CREATE, username, kit.Select("", arg, 0), userrole)
+ ice.Info.UserName = username
+ }
+ return m
+}
+func UserRole(m *ice.Message, username ice.Any) (role string) {
+ if role = VOID; username == ice.Info.UserName {
+ return ROOT
+ }
+ return UserInfo(m, username, USERROLE, ice.MSG_USERROLE)
+}
+func UserNick(m *ice.Message, username ice.Any) (nick string) {
+ return UserInfo(m, username, USERNICK, ice.MSG_USERNICK)
+}
+func UserZone(m *ice.Message, username ice.Any) (zone string) {
+ return UserInfo(m, username, USERZONE, ice.MSG_USERZONE)
+}
+func UserInfo(m *ice.Message, name ice.Any, key, meta string) (value string) {
+ if m.Cmd(USER, name).Tables(func(val ice.Maps) {
+ value = val[key]
+ }).Length() == 0 && kit.Format(name) == m.Option(ice.MSG_USERNAME) {
+ return m.Option(meta)
+ }
+ return
+}
+func UserLogin(m *ice.Message, username, password string) bool {
+ return m.Cmdy(USER, LOGIN, username, password).Option(ice.MSG_USERNAME) != ""
}
diff --git a/base/cli/daemon.go b/base/cli/daemon.go
index f50e296b..e35776e2 100644
--- a/base/cli/daemon.go
+++ b/base/cli/daemon.go
@@ -6,63 +6,67 @@ import (
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/ctx"
+ "shylinux.com/x/icebergs/base/gdb"
"shylinux.com/x/icebergs/base/mdb"
- "shylinux.com/x/icebergs/base/nfs"
kit "shylinux.com/x/toolkits"
)
func _daemon_exec(m *ice.Message, cmd *exec.Cmd) {
if r, ok := m.Optionv(CMD_INPUT).(io.Reader); ok {
- cmd.Stdin = r
+ cmd.Stdin = r // 输入流
}
if w := _system_out(m, CMD_OUTPUT); w != nil {
- cmd.Stdout = w
- cmd.Stderr = w
+ cmd.Stdout, cmd.Stderr = w, w
}
if w := _system_out(m, CMD_ERRPUT); w != nil {
cmd.Stderr = w
}
- // 启动进程
+ h := mdb.HashCreate(m,
+ STATUS, START, ice.CMD, kit.Join(cmd.Args, ice.SP),
+ DIR, cmd.Dir, ENV, kit.Select("", cmd.Env),
+ m.OptionSimple(CMD_OUTPUT, CMD_ERRPUT, mdb.CACHE_CLEAR_ON_EXIT),
+ ).Result()
+
+ // 启动服务
if e := cmd.Start(); m.Warn(e, ice.ErrNotStart, cmd.Args) {
+ mdb.HashModify(m, h, STATUS, ERROR, ERROR, e)
return // 启动失败
}
+ mdb.HashSelectUpdate(m, h, func(value ice.Map) { value[PID] = cmd.Process.Pid })
m.Echo("%d", cmd.Process.Pid)
- m.Go(func() {
- h := m.Cmdx(mdb.INSERT, DAEMON, "", mdb.HASH,
- STATUS, START, ice.CMD, kit.Join(cmd.Args, ice.SP),
- PID, cmd.Process.Pid, DIR, cmd.Dir, ENV, kit.Select("", cmd.Env),
- m.OptionSimple(CMD_OUTPUT, CMD_ERRPUT, mdb.CACHE_CLEAR_ON_EXIT),
- )
-
+ m.Go(func() { // 等待结果
if e := cmd.Wait(); !m.Warn(e, ice.ErrNotStart, cmd.Args) && cmd.ProcessState.ExitCode() == 0 {
m.Cost(CODE, cmd.ProcessState.ExitCode(), ctx.ARGS, cmd.Args)
- m.Cmd(mdb.MODIFY, DAEMON, "", mdb.HASH, mdb.HASH, h, STATUS, STOP)
+ mdb.HashModify(m, mdb.HASH, h, STATUS, STOP)
} else {
- if m.Conf(DAEMON, kit.Keys(mdb.HASH, h, kit.Keym(STATUS))) == START {
- m.Cmd(mdb.MODIFY, DAEMON, "", mdb.HASH, mdb.HASH, h, STATUS, ERROR, ERROR, e)
- }
+ mdb.HashSelectUpdate(m, h, func(value ice.Map) {
+ if value[STATUS] == START {
+ value[STATUS], value[ERROR] = ERROR, e
+ }
+ })
}
+ status := mdb.HashSelectFields(m, h, STATUS)
switch m.Sleep300ms(); cb := m.OptionCB(DAEMON).(type) {
case func(string) bool:
- if !cb(m.Conf(DAEMON, kit.Keys(mdb.HASH, h, kit.Keym(STATUS)))) {
+ if !cb(status) { // 拉起服务
m.Cmdy(DAEMON, cmd.Path, cmd.Args)
}
case func(string):
- cb(m.Conf(DAEMON, kit.Keys(mdb.HASH, h, kit.Keym(STATUS))))
+ cb(status)
case func():
cb()
+ case nil:
default:
- m.Error(true, ice.ErrNotImplement)
+ m.ErrorNotImplement(cb)
}
for _, p := range kit.Simple(CMD_INPUT, CMD_OUTPUT, CMD_ERRPUT) {
kit.Close(m.Optionv(p))
}
})
- m.Sleep("100ms")
}
const (
@@ -87,10 +91,10 @@ const (
RELOAD = "reload"
RESTART = "restart"
- START = "start"
- STOP = "stop"
OPEN = "open"
CLOSE = "close"
+ START = "start"
+ STOP = "stop"
BEGIN = "begin"
END = "end"
@@ -99,61 +103,51 @@ const (
BACK = "back"
FROM = "from"
MAIN = "main"
- KILL = "kill"
)
const DAEMON = "daemon"
func init() {
- Index.Merge(&ice.Context{Configs: ice.Configs{
- DAEMON: {Name: DAEMON, Help: "守护进程", Value: kit.Data(
- nfs.PATH, ice.USR_LOCAL_DAEMON, mdb.FIELD, "time,hash,status,pid,cmd,dir,env",
- )},
- }, Commands: ice.Commands{
+ Index.MergeCommands(ice.Commands{
DAEMON: {Name: "daemon hash auto start prunes", Help: "守护进程", Actions: ice.MergeAction(ice.Actions{
ice.CTX_EXIT: {Hand: func(m *ice.Message, arg ...string) {
- m.Cmd(mdb.PRUNES, DAEMON, "", mdb.HASH, mdb.CACHE_CLEAR_ON_EXIT, ice.TRUE)
+ mdb.HashPrunesValue(m, mdb.CACHE_CLEAR_ON_EXIT, ice.TRUE)
}},
mdb.PRUNES: {Name: "prunes", Help: "清理", Hand: func(m *ice.Message, arg ...string) {
- m.OptionFields(m.Config(mdb.FIELD))
- m.Cmdy(mdb.PRUNES, DAEMON, "", mdb.HASH, STATUS, STOP)
- m.Cmdy(mdb.PRUNES, DAEMON, "", mdb.HASH, STATUS, ERROR)
+ mdb.HashPrunesValue(m, STATUS, ERROR)
+ mdb.HashPrunesValue(m, STATUS, STOP)
}},
START: {Name: "start cmd env dir", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
m.Option(CMD_DIR, m.Option(DIR))
m.Option(CMD_ENV, kit.Split(m.Option(ENV), " ="))
- m.Cmdy(DAEMON, kit.Split(m.Option(ice.CMD)))
+ _daemon_exec(m, _system_cmd(m, kit.Split(m.Option(ice.CMD))...))
}},
RESTART: {Name: "restart", Help: "重启", Hand: func(m *ice.Message, arg ...string) {
- m.Cmdy(DAEMON, STOP).Sleep3s().Cmdy(DAEMON, START)
+ m.Cmdy("", STOP).Sleep3s().Cmdy("", START)
}},
STOP: {Name: "stop", Help: "停止", Hand: func(m *ice.Message, arg ...string) {
m.OptionFields(m.Config(mdb.FIELD))
- m.Cmd(mdb.SELECT, DAEMON, "", mdb.HASH, m.OptionSimple(mdb.HASH)).Tables(func(value ice.Maps) {
- m.Cmd(mdb.MODIFY, DAEMON, "", mdb.HASH, m.OptionSimple(mdb.HASH), STATUS, STOP)
- m.Cmdy(SYSTEM, KILL, value[PID])
+ mdb.HashSelect(m, m.Option(mdb.HASH)).Tables(func(value ice.Maps) {
+ mdb.HashModify(m, m.OptionSimple(mdb.HASH), STATUS, STOP)
+ m.Cmd(gdb.SIGNAL, gdb.KILL, value[PID])
})
- if IsSuccess(m) {
- m.SetAppend()
- }
}},
- }, mdb.HashAction()), Hand: func(m *ice.Message, arg ...string) {
- mdb.HashSelect(m, arg...).Set(ctx.ACTION).Tables(func(value ice.Maps) {
+ }, mdb.HashAction(mdb.FIELD, "time,hash,status,pid,cmd,dir,env")), Hand: func(m *ice.Message, arg ...string) {
+ if mdb.HashSelect(m, arg...).Tables(func(value ice.Maps) {
switch value[STATUS] {
case START:
m.PushButton(RESTART, STOP)
default:
m.PushButton(mdb.REMOVE)
}
- })
-
- if len(arg) == 0 || m.Length() > 0 {
+ }); len(arg) == 0 || m.Length() > 0 {
return
}
+
if len(arg) == 1 {
arg = kit.Split(arg[0])
}
_daemon_exec(m, _system_cmd(m, arg...))
}},
- }})
+ })
}
diff --git a/base/cli/forever.go b/base/cli/forever.go
index a4a92945..b9a60734 100644
--- a/base/cli/forever.go
+++ b/base/cli/forever.go
@@ -5,18 +5,12 @@ import (
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/aaa"
+ "shylinux.com/x/icebergs/base/gdb"
"shylinux.com/x/icebergs/base/nfs"
kit "shylinux.com/x/toolkits"
+ "shylinux.com/x/toolkits/logs"
)
-func _forever_kill(m *ice.Message, s string) {
- if p := m.Cmdx(nfs.CAT, m.Conf("gdb.signal", kit.Keym(nfs.PATH))); p != "" {
- if s != "" {
- m.Cmd(SYSTEM, "kill", "-s", s, p)
- }
- m.Echo(p)
- }
-}
func BinPath(arg ...string) string {
return kit.Join(kit.Simple(arg, kit.Path(ice.BIN), kit.Path(ice.USR_LOCAL_BIN), kit.Path(ice.USR_LOCAL_GO_BIN), kit.Env(PATH)), ice.DF)
}
@@ -24,16 +18,11 @@ func BinPath(arg ...string) string {
const FOREVER = "forever"
func init() {
- const SERVE = "serve"
- const RESTART = "restart"
- Index.Merge(&ice.Context{Commands: ice.Commands{
+ Index.MergeCommands(ice.Commands{
FOREVER: {Name: "forever auto", Help: "启动", Actions: ice.Actions{
- RESTART: {Name: "restart", Help: "重启", Hand: func(m *ice.Message, arg ...string) {
- _forever_kill(m, "INT")
- }},
- SERVE: {Name: "serve", Help: "服务", Hand: func(m *ice.Message, arg ...string) {
+ gdb.START: {Name: "start", Help: "服务", Hand: func(m *ice.Message, arg ...string) {
env := []string{PATH, BinPath(), HOME, kit.Select(kit.Path(""), os.Getenv(HOME))}
- for _, k := range []string{TERM, SHELL, CTX_SHY, CTX_DEV, CTX_OPS, CTX_ARG, CTX_PID, CTX_USER, CTX_SHARE, CTX_RIVER, CTX_DAEMON} {
+ for _, k := range ENV_LIST {
if kit.Env(k) != "" {
env = append(env, k, kit.Env(k))
}
@@ -49,24 +38,27 @@ func init() {
m.Cmd(FOREVER, STOP)
m.Cmdy(FOREVER, kit.Select(os.Args[0], nfs.PWD+ice.BIN_ICE_BIN, kit.FileExists(ice.BIN_ICE_BIN)),
- SERVE, START, ice.DEV, "", aaa.USERNAME, aaa.ROOT, aaa.PASSWORD, aaa.ROOT, arg)
+ "serve", START, ice.DEV, "", aaa.USERNAME, aaa.ROOT, aaa.PASSWORD, aaa.ROOT, arg)
}},
- STOP: {Name: "stop", Help: "停止", Hand: func(m *ice.Message, arg ...string) {
- _forever_kill(m, "QUIT")
+ gdb.RESTART: {Name: "restart", Help: "重启", Hand: func(m *ice.Message, arg ...string) {
+ m.Cmd(gdb.SIGNAL, gdb.RESTART)
+ }},
+ gdb.STOP: {Name: "stop", Help: "停止", Hand: func(m *ice.Message, arg ...string) {
+ m.Cmd(gdb.SIGNAL, gdb.STOP)
}},
}, Hand: func(m *ice.Message, arg ...string) {
if len(arg) == 0 {
- _forever_kill(m, "")
+ m.Cmdy(RUNTIME, BOOTINFO)
return
}
for {
- println(kit.Format("%s run %s", kit.Now(), kit.Join(arg, ice.SP)))
+ logs.Println("run %s", kit.Join(arg, ice.SP))
if m.Sleep("1s"); IsSuccess(m.Cmd(SYSTEM, arg)) {
- println(kit.Format("%s exit", kit.Now()))
- return
+ logs.Println("exit")
+ break
}
}
- }}},
+ }},
})
}
diff --git a/base/cli/mirrors.go b/base/cli/mirrors.go
index af1f0ef8..cf4ed3ab 100644
--- a/base/cli/mirrors.go
+++ b/base/cli/mirrors.go
@@ -1,6 +1,7 @@
package cli
import (
+ "runtime"
"strings"
ice "shylinux.com/x/icebergs"
@@ -8,18 +9,9 @@ import (
kit "shylinux.com/x/toolkits"
)
-func IsAlpine(m *ice.Message, arg ...string) bool {
- if strings.Contains(m.Conf(RUNTIME, "host.OSID"), ALPINE) {
- if len(arg) > 0 {
- m.Cmd(MIRRORS, mdb.CREATE, "cli", arg[0], "cmd", arg[1])
- }
- return true
- }
- return false
-}
-
const (
- OSID = "OSID"
+ CMD = "cmd"
+ OSID = "osid"
ALPINE = "alpine"
CENTOS = "centos"
UBUNTU = "ubuntu"
@@ -28,31 +20,49 @@ const (
const MIRRORS = "mirrors"
func init() {
- Index.Merge(&ice.Context{Commands: ice.Commands{
+ Index.MergeCommands(ice.Commands{
MIRRORS: {Name: "mirrors cli auto", Help: "软件镜像", Actions: ice.MergeAction(ice.Actions{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
- m.Go(func() {
- m.Sleep("1s")
- IsAlpine(m, "curl", "system apk add curl")
- IsAlpine(m, "make", "system apk add make")
- IsAlpine(m, "gcc", "system apk add gcc")
- IsAlpine(m, "vim", "system apk add vim")
- IsAlpine(m, "tmux", "system apk add tmux")
+ m.Conf(m.PrefixKey(), kit.Keys(mdb.HASH), "")
+ IsAlpine(m, "curl")
+ IsAlpine(m, "make")
+ IsAlpine(m, "gcc")
+ IsAlpine(m, "vim")
+ IsAlpine(m, "tmux")
- if IsAlpine(m, "git", "system apk add git"); !IsAlpine(m, "go", "system apk add git go") {
- m.Cmd(MIRRORS, mdb.CREATE, kit.SimpleKV("cli,cmd", "go", "install download https://golang.google.cn/dl/go1.15.5.linux-amd64.tar.gz usr/local"))
+ IsAlpine(m, "git")
+ mdb.ZoneInsert(m, CLI, "go", CMD, kit.Format("install download https://golang.google.cn/dl/go1.15.5.%s-%s.tar.gz usr/local", runtime.GOOS, runtime.GOARCH))
+
+ IsAlpine(m, "node", "nodejs")
+ IsAlpine(m, "java", "openjdk8")
+ IsAlpine(m, "javac", "openjdk8")
+ IsAlpine(m, "mvn", "openjdk8 maven")
+ IsAlpine(m, "python", "python2")
+ IsAlpine(m, "python2")
+ IsAlpine(m, "python3")
+ }},
+ mdb.INSERT: {Name: "insert cli osid cmd", Help: "添加"},
+ CMD: {Name: "cmd cli osid", Help: "安装", Hand: func(m *ice.Message, arg ...string) {
+ osid := kit.Select(m.Conf(RUNTIME, kit.Keys(HOST, OSID)), m.Option(OSID))
+ mdb.ZoneSelectCB(m, m.Option(CLI), func(value ice.Map) {
+ if osid != "" && strings.Contains(osid, kit.Format(value[OSID])) {
+ m.Cmdy(kit.Split(kit.Format(value[CMD])))
}
-
- IsAlpine(m, "node", "system apk add nodejs")
- IsAlpine(m, "python", "system apk add python2")
- IsAlpine(m, "python2", "system apk add python2")
- IsAlpine(m, "python3", "system apk add python3")
- IsAlpine(m, "mvn", "system apk add openjdk8 maven")
- IsAlpine(m, "javac", "system apk add openjdk8")
- IsAlpine(m, "java", "system apk add openjdk8")
})
}},
- mdb.CREATE: {Name: "create cli cmd", Help: "创建"},
- }, mdb.HashAction(mdb.SHORT, "cli", mdb.FIELD, "time,cli,cmd"))},
- }})
+ ALPINE: {Name: "alpine cli cmd", Help: "安装", Hand: func(m *ice.Message, arg ...string) {
+ IsAlpine(m, arg...)
+ }},
+ }, mdb.ZoneAction(mdb.SHORT, CLI, mdb.FIELD, "time,id,osid,cmd"))},
+ })
+}
+
+func IsAlpine(m *ice.Message, arg ...string) bool {
+ if strings.Contains(m.Conf(RUNTIME, kit.Keys(HOST, OSID)), ALPINE) {
+ if len(arg) > 0 {
+ mdb.ZoneInsert(m, CLI, arg[0], OSID, ALPINE, CMD, "system apk add "+kit.Select(arg[0], arg, 1))
+ }
+ return true
+ }
+ return false
}
diff --git a/base/cli/qrcode.go b/base/cli/qrcode.go
index e1096654..c8f5b21b 100644
--- a/base/cli/qrcode.go
+++ b/base/cli/qrcode.go
@@ -31,6 +31,7 @@ func _parse_color(str string) color.Color {
for k := range _trans_web {
list = append(list, k)
}
+ kit.Sort(list)
str = list[rand.Intn(len(list))]
}
if strings.HasPrefix(str, "#") {
@@ -93,24 +94,12 @@ func _qrcode_web(m *ice.Message, text string) {
}
}
-func Color(m *ice.Message, c string, str ice.Any) string {
- wrap, color := `%v`, c
- if m.IsCliUA() {
- wrap, color = "\033[3%sm%v\033[0m", _parse_cli_color(c)
- }
- return fmt.Sprintf(wrap, color, str)
-}
-func ColorRed(m *ice.Message, str ice.Any) string { return Color(m, RED, str) }
-func ColorGreen(m *ice.Message, str ice.Any) string { return Color(m, GREEN, str) }
-func ColorYellow(m *ice.Message, str ice.Any) string { return Color(m, YELLOW, str) }
-
const (
- FG = "fg"
- BG = "bg"
- SIZE = "size"
-
+ FG = "fg"
+ BG = "bg"
DARK = 255
LIGHT = 127
+ SIZE = "size"
)
const (
COLOR = "color"
@@ -129,7 +118,7 @@ const (
const QRCODE = "qrcode"
func init() {
- Index.Merge(&ice.Context{Commands: ice.Commands{
+ Index.MergeCommands(ice.Commands{
QRCODE: {Name: "qrcode text@key fg@key bg@key size auto", Help: "二维码", Actions: ice.Actions{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
ice.AddRender(ice.RENDER_QRCODE, func(m *ice.Message, cmd string, args ...ice.Any) string {
@@ -138,26 +127,32 @@ func init() {
}},
mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) {
switch arg[0] {
- case "text":
- m.Push("text", "hi")
- m.Push("text", "hello")
- m.Push("text", "world")
- case "fg", "bg":
- m.Push("color", "red")
- m.Push("color", "green")
- m.Push("color", "blue")
+ case mdb.TEXT:
+ m.Push(arg[0], "hi", "hello", "world")
+ case FG, BG:
+ m.Push(arg[0], RED, GREEN, BLUE)
}
}},
}, Hand: func(m *ice.Message, arg ...string) {
m.Option(SIZE, kit.Select("240", arg, 3))
m.Option(BG, kit.Select(WHITE, arg, 2))
m.Option(FG, kit.Select(BLUE, arg, 1))
-
if m.IsCliUA() {
- _qrcode_cli(m, kit.Select(ice.Info.Domain, arg, 0))
+ _qrcode_cli(m, kit.Select(kit.Select(ice.Info.Make.Domain, ice.Info.Domain), arg, 0))
} else {
_qrcode_web(m, kit.Select(m.Option(ice.MSG_USERWEB), arg, 0))
}
}},
- }})
+ })
}
+
+func Color(m *ice.Message, c string, str ice.Any) string {
+ wrap, color := `%v`, c
+ if m.IsCliUA() {
+ wrap, color = "\033[3%sm%v\033[0m", _parse_cli_color(c)
+ }
+ return fmt.Sprintf(wrap, color, str)
+}
+func ColorRed(m *ice.Message, str ice.Any) string { return Color(m, RED, str) }
+func ColorGreen(m *ice.Message, str ice.Any) string { return Color(m, GREEN, str) }
+func ColorYellow(m *ice.Message, str ice.Any) string { return Color(m, YELLOW, str) }
diff --git a/base/cli/runtime.go b/base/cli/runtime.go
index 49226f83..6eefdc6c 100644
--- a/base/cli/runtime.go
+++ b/base/cli/runtime.go
@@ -9,6 +9,7 @@ import (
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/aaa"
"shylinux.com/x/icebergs/base/ctx"
+ "shylinux.com/x/icebergs/base/gdb"
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/nfs"
kit "shylinux.com/x/toolkits"
@@ -25,42 +26,49 @@ func _runtime_init(m *ice.Message) {
m.Conf(RUNTIME, kit.Keys(HOST, GOOS), runtime.GOOS)
m.Conf(RUNTIME, kit.Keys(HOST, PID), os.Getpid())
m.Conf(RUNTIME, kit.Keys(HOST, HOME), kit.Env(HOME))
+ m.Conf(RUNTIME, kit.Keys(HOST, MAXPROCS), runtime.GOMAXPROCS(0))
- // 启动信息 boot
- if name, e := os.Hostname(); e == nil {
- m.Conf(RUNTIME, kit.Keys(BOOT, HOSTNAME), kit.Select(name, kit.Env("HOSTNAME")))
+ // 启动目录 boot
+ m.Conf(RUNTIME, kit.Keys(BOOT, HOSTNAME), kit.Env("HOSTNAME"))
+ if name, e := os.Hostname(); e == nil && name != "" {
+ m.Conf(RUNTIME, kit.Keys(BOOT, HOSTNAME), name)
}
- if name, e := os.Getwd(); e == nil {
- name = path.Base(kit.Select(name, kit.Env("PWD")))
- name = kit.Slice(strings.Split(name, ice.PS), -1)[0]
- name = kit.Slice(strings.Split(name, "\\"), -1)[0]
- m.Conf(RUNTIME, kit.Keys(BOOT, PATHNAME), name)
+ m.Conf(RUNTIME, kit.Keys(BOOT, PATHNAME), path.Base(kit.Env("PWD")))
+ if name, e := os.Getwd(); e == nil && name != "" {
+ m.Conf(RUNTIME, kit.Keys(BOOT, PATHNAME), path.Base(name))
}
-
m.Conf(RUNTIME, kit.Keys(BOOT, USERNAME), kit.Select(kit.UserName(), kit.Select(kit.Env("WORKSPACE_GIT_USERNAME"), kit.Env(CTX_USER))))
ice.Info.HostName = m.Conf(RUNTIME, kit.Keys(BOOT, HOSTNAME))
ice.Info.PathName = m.Conf(RUNTIME, kit.Keys(BOOT, PATHNAME))
ice.Info.UserName = m.Conf(RUNTIME, kit.Keys(BOOT, USERNAME))
aaa.UserRoot(ice.Pulse)
- // 启动次数 boot
+ // 启动程序 boot
m.Conf(RUNTIME, kit.Keys(BOOT, mdb.COUNT), kit.Int(m.Conf(RUNTIME, kit.Keys(BOOT, mdb.COUNT)))+1)
bin := _system_find(m, os.Args[0])
m.Conf(RUNTIME, kit.Keys(BOOT, ice.BIN), bin)
if s, e := os.Stat(bin); e == nil {
- m.Conf(RUNTIME, kit.Keys(BOOT, "size"), kit.FmtSize(s.Size()))
+ m.Conf(RUNTIME, kit.Keys(BOOT, nfs.SIZE), kit.FmtSize(s.Size()))
if f, e := os.Open(bin); e == nil {
defer f.Close()
- m.Conf(RUNTIME, kit.Keys(BOOT, "hash"), kit.Hashs(f))
+ m.Conf(RUNTIME, kit.Keys(BOOT, mdb.HASH), kit.Hashs(f))
}
}
// 环境变量 conf
- for _, k := range []string{CTX_SHY, CTX_DEV, CTX_OPS, CTX_ARG, CTX_PID, CTX_USER, CTX_SHARE, CTX_RIVER, CTX_DAEMON} {
- m.Conf(RUNTIME, kit.Keys(CONF, k), kit.Env(k))
+ for _, k := range ENV_LIST {
+ switch m.Conf(RUNTIME, kit.Keys(CONF, k), kit.Env(k)); k {
+ case CTX_PID:
+ ice.Info.PidPath = kit.Select("var/run/ice.pid", kit.Env(k))
+ case CTX_SHARE:
+ ice.Info.CtxShare = kit.Env(k)
+ case CTX_RIVER:
+ ice.Info.CtxRiver = kit.Env(k)
+ }
}
- osid := ""
+ // 系统版本 osid
+ osid := runtime.GOOS
m.Cmd(nfs.CAT, "/etc/os-release", func(text string) {
if ls := kit.Split(text, "="); len(ls) > 1 {
switch ls[0] {
@@ -119,11 +127,11 @@ const (
WINDOWS = "windows"
)
const (
- SHELL = "SHELL"
- TERM = "TERM"
- USER = "USER"
- HOME = "HOME"
PATH = "PATH"
+ HOME = "HOME"
+ USER = "USER"
+ TERM = "TERM"
+ SHELL = "SHELL"
)
const (
CTX_SHY = "ctx_shy"
@@ -131,9 +139,9 @@ const (
CTX_OPS = "ctx_ops"
CTX_POD = "ctx_pod"
CTX_ARG = "ctx_arg"
+ CTX_PID = "ctx_pid"
+ CTX_LOG = "ctx_log"
- CTX_PID = "ctx_pid"
- CTX_LOG = "ctx_log"
CTX_USER = "ctx_user"
CTX_SHARE = "ctx_share"
CTX_RIVER = "ctx_river"
@@ -141,37 +149,37 @@ const (
MAKE_DOMAIN = "make.domain"
)
+
+var ENV_LIST = []string{
+ TERM, SHELL, CTX_SHY, CTX_DEV, CTX_OPS, CTX_ARG, CTX_PID, CTX_USER, CTX_SHARE, CTX_RIVER, CTX_DAEMON,
+}
+
const (
HOSTNAME = "hostname"
PATHNAME = "pathname"
USERNAME = "username"
)
const (
- MAXPROCS = "maxprocs"
IFCONFIG = "ifconfig"
HOSTINFO = "hostinfo"
USERINFO = "userinfo"
PROCINFO = "procinfo"
PROCKILL = "prockill"
- BOOTINFO = "bootinfo"
DISKINFO = "diskinfo"
+ BOOTINFO = "bootinfo"
+ MAXPROCS = "maxprocs"
)
const RUNTIME = "runtime"
func init() {
- Index.Merge(&ice.Context{Configs: ice.Configs{
- RUNTIME: {Name: RUNTIME, Help: "运行环境", Value: kit.Dict()},
- }, Commands: ice.Commands{
- RUNTIME: {Name: "runtime info=ifconfig,hostinfo,hostname,userinfo,procinfo,bootinfo,diskinfo,env,file,route auto", Help: "运行环境", Actions: ice.Actions{
+ Index.MergeCommands(ice.Commands{
+ RUNTIME: {Name: "runtime info=ifconfig,hostinfo,hostname,userinfo,procinfo,diskinfo,bootinfo,api,cli,cmd,env auto", Help: "运行环境", Actions: ice.Actions{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
- m.Cmd(RUNTIME, MAXPROCS, "1")
- _runtime_init(m)
- }},
- MAXPROCS: {Name: "maxprocs", Help: "最大并发", Hand: func(m *ice.Message, arg ...string) {
- if len(arg) > 0 {
- runtime.GOMAXPROCS(kit.Int(m.Conf(RUNTIME, kit.Keys(HOST, "GOMAXPROCS"), kit.Select("1", arg, 0))))
+ cs := m.Target().Configs
+ if _, ok := cs[RUNTIME]; !ok {
+ cs[RUNTIME] = &ice.Config{Value: kit.Dict()}
}
- m.Echo("%d", runtime.GOMAXPROCS(0))
+ _runtime_init(m)
}},
IFCONFIG: {Name: "ifconfig", Help: "网卡配置", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy("tcp.host")
@@ -193,13 +201,37 @@ func init() {
m.StatusTimeCount()
}},
PROCKILL: {Name: "prockill", Help: "结束进程", Hand: func(m *ice.Message, arg ...string) {
- m.Cmdy(SYSTEM, KILL, m.Option("PID"))
+ m.Cmdy(gdb.SIGNAL, gdb.STOP, m.Option("PID"))
m.ProcessRefresh30ms()
}},
DISKINFO: {Name: "diskinfo", Help: "磁盘信息", Hand: func(m *ice.Message, arg ...string) {
_runtime_diskinfo(m)
}},
- "env": {Name: "env", Help: "环境变量", Hand: func(m *ice.Message, arg ...string) {
+ MAXPROCS: {Name: "maxprocs", Help: "最大并发", Hand: func(m *ice.Message, arg ...string) {
+ if len(arg) > 0 {
+ runtime.GOMAXPROCS(kit.Int(m.Conf(RUNTIME, kit.Keys(HOST, MAXPROCS), kit.Select("1", arg, 0))))
+ }
+ m.Echo("%d", runtime.GOMAXPROCS(0))
+ }},
+ API: {Name: "api", Help: "接口命令", Hand: func(m *ice.Message, arg ...string) {
+ for k, v := range ice.Info.Route {
+ m.Push(nfs.PATH, k)
+ m.Push(nfs.FILE, v)
+ }
+ m.Sort(nfs.PATH).StatusTimeCount()
+ }},
+ CLI: {Name: "cli", Help: "文件模块", Hand: func(m *ice.Message, arg ...string) {
+ for k, v := range ice.Info.File {
+ m.Push(nfs.FILE, k)
+ m.Push(mdb.NAME, v)
+ }
+ m.Sort(nfs.FILE).StatusTimeCount()
+ }},
+ CMD: {Name: "cmd", Help: "模块命令", Hand: func(m *ice.Message, arg ...string) {
+ m.OptionFields(ctx.INDEX, mdb.NAME, mdb.HELP)
+ m.Cmdy(ctx.COMMAND, mdb.SEARCH, ctx.COMMAND).StatusTimeCount()
+ }},
+ ENV: {Name: "env", Help: "环境变量", Hand: func(m *ice.Message, arg ...string) {
for _, v := range os.Environ() {
ls := strings.SplitN(v, "=", 2)
m.Push(mdb.NAME, ls[0])
@@ -207,22 +239,6 @@ func init() {
}
m.StatusTimeCount()
}},
- "file": {Name: "file", Help: "模块文件", Hand: func(m *ice.Message, arg ...string) {
- for k, v := range ice.Info.File {
- m.Push(nfs.FILE, k)
- m.Push(mdb.NAME, v)
- }
- m.Sort(nfs.FILE)
- m.StatusTimeCount()
- }},
- "route": {Name: "route", Help: "接口命令", Hand: func(m *ice.Message, arg ...string) {
- for k, v := range ice.Info.Route {
- m.Push(nfs.PATH, k)
- m.Push(nfs.FILE, v)
- }
- m.Sort(nfs.PATH)
- m.StatusTimeCount()
- }},
MAKE_DOMAIN: {Name: "make.domain", Help: "编译主机", Hand: func(m *ice.Message, arg ...string) {
if os.Getenv(CTX_DEV) == "" || os.Getenv(CTX_POD) == "" {
m.Echo(m.Conf(RUNTIME, MAKE_DOMAIN))
@@ -234,8 +250,7 @@ func init() {
if len(arg) > 0 && arg[0] == BOOTINFO {
arg = arg[1:]
}
- m.Cmdy(ctx.CONFIG, RUNTIME, arg)
- m.DisplayStoryJSON()
+ m.Cmdy(ctx.CONFIG, RUNTIME, arg).DisplayStoryJSON()
}},
- }})
+ })
}
diff --git a/base/cli/system.go b/base/cli/system.go
index a2ac4cd8..1addc0c8 100644
--- a/base/cli/system.go
+++ b/base/cli/system.go
@@ -12,43 +12,38 @@ import (
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/nfs"
kit "shylinux.com/x/toolkits"
+ "shylinux.com/x/toolkits/file"
)
func _system_cmd(m *ice.Message, arg ...string) *exec.Cmd {
- // 定制目录
if text := kit.ReadFile(ice.ETC_PATH); len(text) > 0 {
if file := _system_find(m, arg[0], strings.Split(text, ice.NL)...); file != "" {
- m.Debug("cmd: %v", file)
- arg[0] = file
+ m.Log_SELECT("etc path cmd", file)
+ arg[0] = file // 配置目录
}
}
- // 环境变量
env := kit.Simple(m.Optionv(CMD_ENV))
for i := 0; i < len(env)-1; i += 2 {
if env[i] == PATH {
if file := _system_find(m, arg[0], strings.Split(env[i+1], ice.DF)...); file != "" {
- m.Debug("cmd: %v", file)
- arg[0] = file
+ m.Log_SELECT("env path cmd", file)
+ arg[0] = file // 环境变量
}
}
}
- // 自动安装
if _system_find(m, arg[0]) == "" {
- if cmds := m.Cmd(MIRRORS, arg[0]).Append("cmd"); cmds != "" {
- m.Cmd(kit.Split(cmds))
- if file := _system_find(m, arg[0]); file != "" {
- m.Debug("cmd: %v", file)
- arg[0] = file
- }
+ m.Cmd(MIRRORS, CMD, arg[0])
+ if file := _system_find(m, arg[0]); file != "" {
+ m.Log_SELECT("mirrors cmd", file)
+ arg[0] = file // 软件镜像
}
}
-
cmd := exec.Command(arg[0], arg[1:]...)
// 运行目录
if cmd.Dir = m.Option(CMD_DIR); len(cmd.Dir) > 0 {
if m.Log_EXPORT(CMD_DIR, cmd.Dir); !kit.FileExists(cmd.Dir) {
- nfs.MkdirAll(m, cmd.Dir)
+ file.MkdirAll(cmd.Dir, ice.MOD_DIR)
}
}
// 环境变量
@@ -61,13 +56,11 @@ func _system_cmd(m *ice.Message, arg ...string) *exec.Cmd {
return cmd
}
func _system_out(m *ice.Message, out string) io.Writer {
- defer func() { m.Warn(recover(), "output", out) }()
-
if w, ok := m.Optionv(out).(io.Writer); ok {
return w
} else if m.Option(out) == "" {
return nil
- } else if f, p, e := kit.Create(m.Option(out)); m.Assert(e) {
+ } else if f, p, e := file.CreateFile(m.Option(out)); m.Assert(e) {
m.Log_EXPORT(out, p)
m.Optionv(out, f)
return f
@@ -95,20 +88,18 @@ func _system_find(m *ice.Message, bin string, dir ...string) string {
return ""
}
func _system_exec(m *ice.Message, cmd *exec.Cmd) {
- // 输入流
if r, ok := m.Optionv(CMD_INPUT).(io.Reader); ok {
- cmd.Stdin = r
+ cmd.Stdin = r // 输入流
}
-
- // 输出流
if w := _system_out(m, CMD_OUTPUT); w != nil {
- cmd.Stdout, cmd.Stderr = w, w
+ cmd.Stdout, cmd.Stderr = w, w // 输出流
if w := _system_out(m, CMD_ERRPUT); w != nil {
cmd.Stderr = w
}
} else {
out := bytes.NewBuffer(make([]byte, 0, ice.MOD_BUFS))
err := bytes.NewBuffer(make([]byte, 0, ice.MOD_BUFS))
+ cmd.Stdout, cmd.Stderr = out, err
defer func() {
m.Push(CMD_OUT, out.String())
m.Push(CMD_ERR, err.String())
@@ -116,7 +107,6 @@ func _system_exec(m *ice.Message, cmd *exec.Cmd) {
m.SetAppend()
}
}()
- cmd.Stdout, cmd.Stderr = out, err
}
// 执行命令
@@ -126,16 +116,6 @@ func _system_exec(m *ice.Message, cmd *exec.Cmd) {
m.Push(mdb.TIME, m.Time()).Push(CODE, int(cmd.ProcessState.ExitCode()))
}
-func IsSuccess(m *ice.Message) bool {
- return m.Append(CODE) == "0" || m.Append(CODE) == ""
-}
-func SystemFind(m *ice.Message, bin string, dir ...string) string {
- if text := kit.ReadFile(ice.ETC_PATH); len(text) > 0 {
- dir = append(dir, strings.Split(text, ice.NL)...)
- }
- dir = append(dir, strings.Split(kit.Env(PATH), ice.DF)...)
- return _system_find(m, bin, dir...)
-}
const (
CMD_DIR = "cmd_dir"
@@ -145,16 +125,14 @@ const (
CMD_OUTPUT = "cmd_output"
CMD_ERRPUT = "cmd_errput"
- CMD_OUT = "cmd_out"
CMD_ERR = "cmd_err"
+ CMD_OUT = "cmd_out"
)
const SYSTEM = "system"
func init() {
- Index.Merge(&ice.Context{Configs: ice.Configs{
- SYSTEM: {Name: SYSTEM, Help: "系统命令", Value: kit.Data(mdb.FIELD, "time,id,cmd")},
- }, Commands: ice.Commands{
+ Index.MergeCommands(ice.Commands{
SYSTEM: {Name: "system cmd run", Help: "系统命令", Actions: ice.Actions{
nfs.FIND: {Name: "find", Help: "查找", Hand: func(m *ice.Message, arg ...string) {
m.Echo(_system_find(m, arg[0], arg[1:]...))
@@ -168,37 +146,28 @@ func init() {
m.Cmdy(nfs.CAT, ice.ETC_PATH)
}},
}, Hand: func(m *ice.Message, arg ...string) {
- if len(arg) == 0 {
- mdb.ListSelect(m, arg...)
- return
- }
- // m.Grow(SYSTEM, "", kit.Dict(mdb.TIME, m.Time(), ice.CMD, kit.Join(arg, ice.SP)))
-
if len(arg) == 1 {
arg = kit.Split(arg[0])
}
- if kit.Ext(arg[0]) == nfs.SH && arg[0] != nfs.SH && kit.FileExists(path.Join(ice.SRC, arg[0])) {
- arg = []string{nfs.SH, path.Join(ice.SRC, arg[0])}
- }
_system_exec(m, _system_cmd(m, arg...))
}},
- }})
+ })
}
-type buffer struct {
- m *ice.Message
- n string
-}
-
-func (b *buffer) Write(buf []byte) (int, error) {
- if b.m.IsCliUA() {
- print(string(buf))
- } else {
- b.m.PushNoticeGrow(string(buf))
- }
- return len(buf), nil
-}
-func (b *buffer) Close() error { return nil }
func PushStream(m *ice.Message) {
- m.Option(CMD_OUTPUT, &buffer{m: m, n: m.Option(ice.MSG_DAEMON)})
+ m.Option(CMD_OUTPUT, file.NewWriteCloser(func(buf []byte) (int, error) {
+ m.PushNoticeGrow(string(buf))
+ return len(buf), nil
+ }, func() error { m.PushNoticeToast("done"); return nil }))
+}
+
+func IsSuccess(m *ice.Message) bool {
+ return m.Append(CODE) == "0" || m.Append(CODE) == ""
+}
+func SystemFind(m *ice.Message, bin string, dir ...string) string {
+ if text := kit.ReadFile(ice.ETC_PATH); len(text) > 0 {
+ dir = append(dir, strings.Split(text, ice.NL)...)
+ }
+ dir = append(dir, strings.Split(kit.Env(PATH), ice.DF)...)
+ return _system_find(m, bin, dir...)
}
diff --git a/base/ctx/command.go b/base/ctx/command.go
index 9efdb3d3..99756fa9 100644
--- a/base/ctx/command.go
+++ b/base/ctx/command.go
@@ -12,7 +12,7 @@ import (
)
func _command_list(m *ice.Message, name string) {
- if kit.FileExists(path.Join(ice.SRC, name)) {
+ if nfs.ExistsFile(m, path.Join(ice.SRC, name)) {
switch kit.Ext(name) {
case nfs.JS:
m.Push(DISPLAY, ice.FileURI(name))
@@ -22,8 +22,8 @@ func _command_list(m *ice.Message, name string) {
name = ice.GetFileCmd(name)
default:
- if file, msg := name, m.Cmd(mdb.RENDER, kit.Ext(name)); msg.Length() > 0 {
- m.Push(ARGS, kit.Format(kit.List(file)))
+ if msg := m.Cmd(mdb.RENDER, kit.Ext(name)); msg.Length() > 0 {
+ m.Push(ARGS, kit.Format(kit.List(name)))
name = kit.Keys(msg.Append(mdb.TEXT), msg.Append(mdb.NAME))
}
}
@@ -68,10 +68,45 @@ func _command_search(m *ice.Message, kind, name, text string) {
kit.SimpleKV("", s.Cap(ice.CTX_FOLLOW), cmd.Name, cmd.Help),
CONTEXT, s.Cap(ice.CTX_FOLLOW), COMMAND, key,
INDEX, kit.Keys(s.Cap(ice.CTX_FOLLOW), key),
+ mdb.HELP, cmd.Help,
)
})
}
+const (
+ INDEX = "index"
+ ARGS = "args"
+ STYLE = "style"
+ DISPLAY = "display"
+ ACTION = "action"
+
+ CAN_PLUGIN = "can.plugin"
+)
+const COMMAND = "command"
+
+func init() {
+ Index.MergeCommands(ice.Commands{
+ COMMAND: {Name: "command key auto", Help: "命令", Actions: ice.Actions{
+ ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
+ m.Cmd(aaa.ROLE, aaa.WHITE, aaa.VOID, m.Prefix(COMMAND))
+ m.Cmd(aaa.ROLE, aaa.WHITE, aaa.VOID, COMMAND)
+ }},
+ mdb.SEARCH: {Name: "search type name text", Help: "搜索", Hand: func(m *ice.Message, arg ...string) {
+ if arg[0] == m.CommandKey() || len(arg) > 1 && arg[1] != "" {
+ _command_search(m, arg[0], kit.Select("", arg, 1), kit.Select("", arg, 2))
+ }
+ }},
+ }, Hand: func(m *ice.Message, arg ...string) {
+ if len(arg) == 0 {
+ arg = append(arg, "")
+ }
+ for _, key := range arg {
+ _command_list(m, key)
+ }
+ }},
+ })
+}
+
func CmdAction(args ...ice.Any) ice.Actions {
return ice.Actions{ice.CTX_INIT: mdb.AutoConfig(args...),
COMMAND: {Name: "command", Help: "命令", Hand: func(m *ice.Message, arg ...string) {
@@ -90,37 +125,3 @@ func CmdAction(args ...ice.Any) ice.Actions {
}},
}
}
-
-const (
- INDEX = "index"
- ARGS = "args"
- STYLE = "style"
- DISPLAY = "display"
- ACTION = "action"
-
- CAN_PLUGIN = "can.plugin"
-)
-const COMMAND = "command"
-
-func init() {
- Index.Merge(&ice.Context{Commands: ice.Commands{
- COMMAND: {Name: "command key auto", Help: "命令", Actions: ice.Actions{
- ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
- m.Cmd(aaa.ROLE, aaa.WHITE, aaa.VOID, m.Prefix(COMMAND))
- m.Cmd(aaa.ROLE, aaa.WHITE, aaa.VOID, COMMAND)
- }},
- mdb.SEARCH: {Name: "search type name text", Help: "搜索", Hand: func(m *ice.Message, arg ...string) {
- if arg[0] == m.CommandKey() || len(arg) > 1 && arg[1] != "" {
- _command_search(m, arg[0], kit.Select("", arg, 1), kit.Select("", arg, 2))
- }
- }},
- }, Hand: func(m *ice.Message, arg ...string) {
- if len(arg) == 0 {
- arg = append(arg, "")
- }
- for _, key := range arg {
- _command_list(m, key)
- }
- }},
- }})
-}
diff --git a/base/ctx/config.go b/base/ctx/config.go
index bf3d7868..5056b160 100644
--- a/base/ctx/config.go
+++ b/base/ctx/config.go
@@ -2,7 +2,6 @@ package ctx
import (
"encoding/json"
- "os"
"path"
"strings"
@@ -10,23 +9,12 @@ import (
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/nfs"
kit "shylinux.com/x/toolkits"
+ "shylinux.com/x/toolkits/miss"
)
-func _config_list(m *ice.Message) {
- for k, v := range m.Source().Configs {
- if k[0] == '/' || k[0] == '_' {
- continue // 内部配置
- }
-
- m.Push(mdb.KEY, k)
- m.Push(mdb.NAME, v.Name)
- m.Push(mdb.VALUE, kit.Format(v.Value))
- }
- m.Sort(mdb.KEY)
-}
func _config_save(m *ice.Message, name string, arg ...string) {
- name = path.Join(m.Config(nfs.PATH), name)
- if f, p, e := kit.Create(name); m.Assert(e) {
+ name = path.Join(ice.VAR_CONF, name)
+ if f, p, e := miss.CreateFile(name); m.Assert(e) {
defer f.Close()
msg := m.Spawn(m.Source())
@@ -39,16 +27,16 @@ func _config_save(m *ice.Message, name string, arg ...string) {
// 保存配置
if s, e := json.MarshalIndent(data, "", " "); m.Assert(e) {
- if n, e := f.Write(s); m.Assert(e) {
- m.Log_EXPORT(CONFIG, name, nfs.FILE, p, nfs.SIZE, n)
+ if _, e := f.Write(s); m.Assert(e) {
+ // m.Log_EXPORT(CONFIG, name, nfs.FILE, p, nfs.SIZE, n)
}
}
m.Echo(p)
}
}
func _config_load(m *ice.Message, name string, arg ...string) {
- name = path.Join(m.Config(nfs.PATH), name)
- if f, e := os.Open(name); e == nil {
+ name = path.Join(ice.VAR_CONF, name)
+ if f, e := miss.OpenFile(name); e == nil {
defer f.Close()
msg := m.Spawn(m.Source())
@@ -58,7 +46,7 @@ func _config_load(m *ice.Message, name string, arg ...string) {
// 加载配置
for k, v := range data {
msg.Search(k, func(p *ice.Context, s *ice.Context, key string) {
- m.Log_IMPORT(CONFIG, kit.Keys(s.Name, key), nfs.FILE, name)
+ // m.Log_IMPORT(CONFIG, kit.Keys(s.Name, key), nfs.FILE, name)
if s.Configs[key] == nil {
s.Configs[key] = &ice.Config{}
}
@@ -83,11 +71,17 @@ func _config_make(m *ice.Message, key string, arg ...string) {
m.Echo(kit.Formats(msg.Confv(key)))
}
}
-func _config_rich(m *ice.Message, key string, sub string, arg ...string) {
- m.Rich(key, sub, kit.Data(arg))
-}
-func _config_grow(m *ice.Message, key string, sub string, arg ...string) {
- m.Grow(key, sub, kit.Dict(arg))
+func _config_list(m *ice.Message) {
+ for k, v := range m.Source().Configs {
+ if k[0] == '/' || k[0] == '_' {
+ continue // 内部配置
+ }
+
+ m.Push(mdb.KEY, k)
+ m.Push(mdb.NAME, v.Name)
+ m.Push(mdb.VALUE, kit.Format(v.Value))
+ }
+ m.Sort(mdb.KEY)
}
const (
@@ -99,9 +93,7 @@ const (
const CONFIG = "config"
func init() {
- Index.Merge(&ice.Context{Configs: ice.Configs{
- CONFIG: {Name: CONFIG, Help: "配置", Value: kit.Data(nfs.PATH, ice.VAR_CONF)},
- }, Commands: ice.Commands{
+ Index.MergeCommands(ice.Commands{
CONFIG: {Name: "config key auto reset", Help: "配置", Actions: ice.Actions{
SAVE: {Name: "save", Help: "保存", Hand: func(m *ice.Message, arg ...string) {
_config_save(m, arg[0], arg[1:]...)
@@ -110,10 +102,10 @@ func init() {
_config_load(m, arg[0], arg[1:]...)
}},
RICH: {Name: "rich", Help: "富有", Hand: func(m *ice.Message, arg ...string) {
- _config_rich(m, arg[0], arg[1], arg[2:]...)
+ m.Cmdy(mdb.INSERT, arg[0], arg[1], mdb.HASH, arg[2:])
}},
GROW: {Name: "grow", Help: "成长", Hand: func(m *ice.Message, arg ...string) {
- _config_grow(m, arg[0], arg[1], arg[2:]...)
+ m.Cmdy(mdb.INSERT, arg[0], arg[1], mdb.LIST, arg[2:])
}},
"list": {Name: "list", Help: "列表", Hand: func(m *ice.Message, arg ...string) {
list := []ice.Any{}
@@ -134,5 +126,5 @@ func init() {
_config_make(m, arg[0], arg[1:]...)
m.DisplayStoryJSON()
}},
- }})
+ })
}
diff --git a/base/ctx/context.go b/base/ctx/context.go
index e5345ebb..c7494222 100644
--- a/base/ctx/context.go
+++ b/base/ctx/context.go
@@ -5,6 +5,7 @@ import (
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/mdb"
+ "shylinux.com/x/icebergs/base/nfs"
kit "shylinux.com/x/toolkits"
)
@@ -19,35 +20,20 @@ func _context_list(m *ice.Message, sub *ice.Context, name string) {
m.Push(mdb.HELP, s.Help)
})
}
-func Inputs(m *ice.Message, field string) bool {
- switch strings.TrimPrefix(field, "extra.") {
- case ice.POD:
- m.Cmdy("route")
- case ice.CTX:
- m.Cmdy(CONTEXT)
- case ice.CMD:
- m.Cmdy(CONTEXT, kit.Select(m.Option(ice.CTX), m.Option(kit.Keys(mdb.EXTRA, ice.CTX))), COMMAND)
- case ice.ARG:
-
- default:
- return false
- }
- return true
-}
const CONTEXT = "context"
func init() {
- Index.Merge(&ice.Context{Commands: ice.Commands{
+ Index.MergeCommands(ice.Commands{
CONTEXT: {Name: "context name=web action=context,command,config key auto spide", Help: "模块", Actions: ice.MergeAction(ice.Actions{
"spide": {Name: "spide", Help: "架构图", Hand: func(m *ice.Message, arg ...string) {
if len(arg) == 0 || arg[1] == CONTEXT { // 模块列表
m.Cmdy(CONTEXT, kit.Select(ice.ICE, arg, 0), CONTEXT)
- m.Display("/plugin/story/spide.js?prefix=spide", "root", kit.Select(ice.ICE, arg, 0), "split", ice.PT)
+ m.DisplayStorySpide("prefix", m.ActionKey(), nfs.ROOT, kit.Select(ice.ICE, arg, 0), "split", ice.PT)
} else if index := kit.Keys(arg[1]); strings.HasSuffix(index, arg[2]) { // 命令列表
m.Cmdy(CONTEXT, index, COMMAND).Tables(func(value ice.Maps) {
- m.Push("file", arg[1])
+ m.Push(nfs.FILE, arg[1])
})
} else { // 命令详情
@@ -72,5 +58,20 @@ func init() {
}
})
}},
- }})
+ })
+}
+func Inputs(m *ice.Message, field string) bool {
+ switch strings.TrimPrefix(field, "extra.") {
+ case ice.POD:
+ m.Cmdy("route")
+ case ice.CTX:
+ m.Cmdy(CONTEXT)
+ case ice.CMD:
+ m.Cmdy(CONTEXT, kit.Select(m.Option(ice.CTX), m.Option(kit.Keys(mdb.EXTRA, ice.CTX))), COMMAND)
+ case ice.ARG:
+
+ default:
+ return false
+ }
+ return true
}
diff --git a/base/ctx/message.go b/base/ctx/message.go
index ef312d9b..7c70aa48 100644
--- a/base/ctx/message.go
+++ b/base/ctx/message.go
@@ -12,7 +12,7 @@ import (
const MESSAGE = "message"
func init() {
- Index.Merge(&ice.Context{Commands: ice.Commands{
+ Index.MergeCommands(ice.Commands{
MESSAGE: {Name: "message", Help: "消息", Hand: func(m *ice.Message, arg ...string) {
t := reflect.TypeOf(m)
for i := 0; i < t.NumMethod(); i++ {
@@ -22,5 +22,5 @@ func init() {
m.Push(mdb.TEXT, strings.Split(p, ice.ICEBERGS+"/")[1])
}
}},
- }})
+ })
}
diff --git a/base/gdb/event.go b/base/gdb/event.go
index cda2a7f5..2501dba6 100644
--- a/base/gdb/event.go
+++ b/base/gdb/event.go
@@ -6,33 +6,19 @@ import (
kit "shylinux.com/x/toolkits"
)
-func _event_listen(m *ice.Message, event string, cmd string) {
- m.Cmdy(mdb.INSERT, EVENT, "", mdb.HASH, EVENT, event)
- m.Cmdy(mdb.INSERT, EVENT, "", mdb.ZONE, event, ice.CMD, cmd)
-}
-func _event_action(m *ice.Message, event string, arg ...string) {
- mdb.ZoneSelect(m, event).Tables(func(value ice.Maps) {
- m.Cmd(kit.Split(value[ice.CMD]), event, arg).Cost(EVENT, event, ice.ARG, arg)
- })
-}
-
const EVENT = "event"
func init() {
- Index.Merge(&ice.Context{Configs: ice.Configs{
- EVENT: {Name: EVENT, Help: "事件流", Value: kit.Data(mdb.SHORT, EVENT, mdb.FIELD, "time,id,cmd")},
- }, Commands: ice.Commands{
- EVENT: {Name: "event event id auto listen", Help: "事件流", Actions: ice.MergeAction(ice.Actions{
+ Index.MergeCommands(ice.Commands{
+ EVENT: {Name: "event event id auto listen happen", Help: "事件流", Actions: ice.MergeAction(ice.Actions{
LISTEN: {Name: "listen event cmd", Help: "监听", Hand: func(m *ice.Message, arg ...string) {
- _event_listen(m, m.Option(EVENT), m.Option(ice.CMD))
+ mdb.ZoneInsert(m, m.OptionSimple(EVENT, ice.CMD))
}},
HAPPEN: {Name: "happen event arg", Help: "触发", Hand: func(m *ice.Message, arg ...string) {
- _event_action(m, m.Option(EVENT), arg[2:]...)
+ mdb.ZoneSelect(m, m.Option(EVENT)).Tables(func(value ice.Maps) {
+ m.Cmd(kit.Split(value[ice.CMD]), m.Option(EVENT), arg[2:]).Cost()
+ })
}},
- }, mdb.ZoneAction()), Hand: func(m *ice.Message, arg ...string) {
- if mdb.ZoneSelect(m, arg...); len(arg) == 0 {
- m.PushAction(HAPPEN, mdb.REMOVE)
- }
- }},
- }})
+ }, mdb.ZoneAction(mdb.SHORT, EVENT, mdb.FIELD, "time,id,cmd"))},
+ })
}
diff --git a/base/gdb/gdb.go b/base/gdb/gdb.go
index 899037d3..0a4927b9 100644
--- a/base/gdb/gdb.go
+++ b/base/gdb/gdb.go
@@ -2,6 +2,7 @@ package gdb
import (
"os"
+ "strings"
"time"
ice "shylinux.com/x/icebergs"
@@ -10,48 +11,56 @@ import (
type Frame struct {
s chan os.Signal
- t time.Duration
- e chan bool
}
func (f *Frame) Spawn(m *ice.Message, c *ice.Context, arg ...string) ice.Server {
return &Frame{}
}
func (f *Frame) Begin(m *ice.Message, arg ...string) ice.Server {
+ list := []string{}
+ for k := range ice.Info.File {
+ if strings.HasPrefix(k, ice.Info.Make.Path+ice.PS) {
+ list = append(list, k)
+ }
+ }
+ for _, k := range list {
+ ice.Info.File["/require/"+strings.TrimPrefix(k, ice.Info.Make.Path+ice.PS)] = ice.Info.File[k]
+ delete(ice.Info.File, k)
+ }
+
f.s = make(chan os.Signal, ice.MOD_CHAN)
- f.e = make(chan bool, 1)
return f
}
func (f *Frame) Start(m *ice.Message, arg ...string) bool {
- f.t = kit.Duration(m.Conf(TIMER, kit.Keym(TICK)))
+ t := kit.Duration(m.Conf(TIMER, kit.Keym(TICK)))
+ enable := m.Conf(TIMER, kit.Keym("enable")) == ice.TRUE
+
for {
select {
- case <-f.e:
- return true
+ case <-time.Tick(t):
+ if enable {
+ m.Cmd(TIMER, HAPPEN)
+ }
- // case <-time.Tick(f.t):
- // // m.Cmd(TIMER, ACTION)
-
- case s := <-f.s:
+ case s, ok := <-f.s:
+ if !ok {
+ return true
+ }
m.Cmd(SIGNAL, HAPPEN, SIGNAL, s)
}
}
return true
}
func (f *Frame) Close(m *ice.Message, arg ...string) bool {
- f.e <- true
+ close(f.s)
return true
}
const GDB = "gdb"
var Index = &ice.Context{Name: GDB, Help: "事件模块", Commands: ice.Commands{
- ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
- m.Load(TIMER)
- }},
- ice.CTX_EXIT: {Hand: func(m *ice.Message, arg ...string) {
- m.Save(TIMER)
- }},
+ ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { m.Load(TIMER, ROUTINE) }},
+ ice.CTX_EXIT: {Hand: func(m *ice.Message, arg ...string) { m.Save(TIMER, ROUTINE) }},
}}
-func init() { ice.Index.Register(Index, &Frame{}, ROUTINE, SIGNAL, EVENT, TIMER) }
+func init() { ice.Index.Register(Index, &Frame{}, SIGNAL, TIMER, EVENT, ROUTINE) }
diff --git a/base/gdb/routine.go b/base/gdb/routine.go
index af0acd44..45deafbc 100644
--- a/base/gdb/routine.go
+++ b/base/gdb/routine.go
@@ -4,31 +4,43 @@ import (
"path"
ice "shylinux.com/x/icebergs"
- "shylinux.com/x/icebergs/base/cli"
"shylinux.com/x/icebergs/base/mdb"
kit "shylinux.com/x/toolkits"
+ "shylinux.com/x/toolkits/logs"
)
const ROUTINE = "routine"
func init() {
- Index.Merge(&ice.Context{Configs: ice.Configs{
- ROUTINE: {Name: ROUTINE, Help: "协程池", Value: kit.Data(mdb.SHORT, "time,hash,status,fileline")},
- }, Commands: ice.Commands{
+ Index.MergeCommands(ice.Commands{
ROUTINE: {Name: "routine hash auto prunes", Help: "协程池", Actions: ice.MergeAction(ice.Actions{
- mdb.CREATE: {Name: "create fileline status", Help: "创建"},
- mdb.PRUNES: {Name: "prunes", Help: "清理", Hand: func(m *ice.Message, arg ...string) {
- m.OptionFields(m.Config(mdb.SHORT))
- m.Cmdy(mdb.PRUNES, ROUTINE, "", mdb.HASH, cli.STATUS, cli.STOP)
- m.Cmdy(mdb.PRUNES, ROUTINE, "", mdb.HASH, cli.STATUS, cli.ERROR)
+ mdb.CREATE: {Name: "create name", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
+ m.Go(func() {
+ cb := m.OptionCB(ROUTINE)
+ h := mdb.HashCreate(m, m.OptionSimple(mdb.NAME), mdb.STATUS, START, ice.CMD, logs.FileLine(cb, 100)).Result()
+ defer func() {
+ if e := recover(); e == nil {
+ mdb.HashModify(m, mdb.HASH, h, mdb.STATUS, STOP)
+ } else {
+ mdb.HashModify(m, mdb.HASH, h, mdb.STATUS, ERROR, ERROR, e)
+ }
+ }()
+ switch cb := cb.(type) {
+ case []string:
+ m.Cmd(kit.Split(kit.Join(cb)))
+ case string:
+ m.Cmd(kit.Split(cb))
+ case func():
+ cb()
+ default:
+ m.ErrorNotImplement(cb)
+ }
+ })
}},
"inner": {Name: "inner", Help: "源码", Hand: func(m *ice.Message, arg ...string) {
- ls := kit.Split(m.Option("fileline"), ":")
+ ls := kit.Split(m.Option(ice.CMD), ":")
m.ProcessCommand("inner", []string{path.Dir(ls[0]), path.Base(ls[0]), ls[1]}, arg...)
}},
- }, mdb.HashAction()), Hand: func(m *ice.Message, arg ...string) {
- mdb.HashSelect(m, arg...)
- m.PushAction("inner", mdb.REMOVE)
- }},
- }})
+ }, mdb.HashActionStatus(mdb.FIELD, "time,hash,name,status,cmd", mdb.ACTION, "inner"))},
+ })
}
diff --git a/base/gdb/signal.go b/base/gdb/signal.go
index 829f58ef..40fd4493 100644
--- a/base/gdb/signal.go
+++ b/base/gdb/signal.go
@@ -1,23 +1,22 @@
package gdb
import (
+ "fmt"
"os"
"os/signal"
- "path"
"syscall"
ice "shylinux.com/x/icebergs"
- "shylinux.com/x/icebergs/base/cli"
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/nfs"
kit "shylinux.com/x/toolkits"
- log "shylinux.com/x/toolkits/logs"
+ "shylinux.com/x/toolkits/logs"
)
func _signal_listen(m *ice.Message, s int, arg ...string) {
if f, ok := m.Target().Server().(*Frame); ok {
- m.Cmdy(mdb.INSERT, SIGNAL, "", mdb.HASH, arg)
signal.Notify(f.s, syscall.Signal(s))
+ mdb.HashCreate(m, SIGNAL, s, arg)
}
}
func _signal_action(m *ice.Message, arg ...string) {
@@ -25,6 +24,65 @@ func _signal_action(m *ice.Message, arg ...string) {
m.Cmdy(kit.Split(value[ice.CMD]))
})
}
+func _signal_process(m *ice.Message, p string, s os.Signal) {
+ if p == "" {
+ p = m.Cmdx(nfs.CAT, ice.Info.PidPath)
+ }
+ if p == "" {
+ p = kit.Format(os.Getpid())
+ }
+ if p, e := os.FindProcess(kit.Int(p)); e == nil {
+ p.Signal(s)
+ }
+}
+
+const (
+ PID = "pid"
+)
+const (
+ LISTEN = ice.LISTEN
+ HAPPEN = ice.HAPPEN
+
+ START = ice.START
+ RESTART = ice.RESTART
+ STOP = ice.STOP
+ ERROR = ice.ERROR
+ KILL = "kill"
+)
+const SIGNAL = "signal"
+
+func init() {
+ Index.MergeCommands(ice.Commands{
+ SIGNAL: {Name: "signal signal auto listen", Help: "信号器", Actions: ice.MergeAction(ice.Actions{
+ ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
+ _signal_listen(m, 2, mdb.NAME, "重启", ice.CMD, "exit 1")
+ _signal_listen(m, 3, mdb.NAME, "退出", ice.CMD, "exit 0")
+ if f, p, e := logs.CreateFile(ice.Info.PidPath); !m.Warn(e) {
+ defer f.Close()
+ fmt.Fprint(f, os.Getpid())
+ m.Log_CREATE(nfs.FILE, p)
+ }
+ }},
+ LISTEN: {Name: "listen signal name cmd", Help: "监听", Hand: func(m *ice.Message, arg ...string) {
+ _signal_listen(m, kit.Int(m.Option(SIGNAL)), arg...)
+ }},
+ HAPPEN: {Name: "happen signal", Help: "触发", Hand: func(m *ice.Message, arg ...string) {
+ _signal_action(m, m.Option(SIGNAL))
+ }},
+ RESTART: {Name: "restart pid", Help: "触发", Hand: func(m *ice.Message, arg ...string) {
+ _signal_process(m, m.Option(PID), syscall.SIGINT)
+ }},
+ STOP: {Name: "stop pid", Help: "触发", Hand: func(m *ice.Message, arg ...string) {
+ _signal_process(m, m.Option(PID), syscall.SIGQUIT)
+ }},
+ KILL: {Name: "kill pid signal", Help: "触发", Hand: func(m *ice.Message, arg ...string) {
+ _signal_process(m, m.Option(PID), syscall.Signal(kit.Int(kit.Select("9", m.Option(SIGNAL)))))
+ }},
+ }, mdb.HashAction(mdb.SHORT, SIGNAL, mdb.FIELD, "time,signal,name,cmd", mdb.ACTION, HAPPEN)), Hand: func(m *ice.Message, arg ...string) {
+ mdb.HashSelect(m, arg...).Sort(SIGNAL)
+ }},
+ })
+}
func SignalNotify(m *ice.Message, sig int, cb func()) {
ch := make(chan os.Signal)
@@ -37,39 +95,3 @@ func SignalNotify(m *ice.Message, sig int, cb func()) {
}
})
}
-
-const (
- LISTEN = ice.LISTEN
- HAPPEN = ice.HAPPEN
-)
-const SIGNAL = "signal"
-
-func init() {
- Index.Merge(&ice.Context{Configs: ice.Configs{
- SIGNAL: {Name: SIGNAL, Help: "信号器", Value: kit.Data(
- mdb.SHORT, SIGNAL, mdb.FIELD, "time,signal,name,cmd", nfs.PATH, path.Join(ice.VAR_RUN, "ice.pid"),
- )},
- }, Commands: ice.Commands{
- SIGNAL: {Name: "signal signal auto listen", Help: "信号器", Actions: ice.MergeAction(ice.Actions{
- ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
- if log.LogDisable {
- return // 禁用日志
- }
- m.Cmd(nfs.SAVE, kit.Select(m.Config(nfs.PATH), m.Conf(cli.RUNTIME, kit.Keys(cli.CONF, cli.CTX_PID))),
- m.Conf(cli.RUNTIME, kit.Keys(cli.HOST, cli.PID)))
-
- m.Cmd(SIGNAL, LISTEN, SIGNAL, "3", mdb.NAME, "退出", ice.CMD, "exit 0")
- m.Cmd(SIGNAL, LISTEN, SIGNAL, "2", mdb.NAME, "重启", ice.CMD, "exit 1")
- }},
- LISTEN: {Name: "listen signal name cmd", Help: "监听", Hand: func(m *ice.Message, arg ...string) {
- _signal_listen(m, kit.Int(m.Option(SIGNAL)), arg...)
- }},
- HAPPEN: {Name: "happen signal", Help: "触发", Hand: func(m *ice.Message, arg ...string) {
- _signal_action(m, m.Option(SIGNAL))
- }},
- }, mdb.HashAction()), Hand: func(m *ice.Message, arg ...string) {
- mdb.HashSelect(m, arg...).Sort(SIGNAL)
- m.PushAction(HAPPEN, mdb.REMOVE)
- }},
- }})
-}
diff --git a/base/gdb/timer.go b/base/gdb/timer.go
index 493d8d80..e2aa64ff 100644
--- a/base/gdb/timer.go
+++ b/base/gdb/timer.go
@@ -4,62 +4,43 @@ import (
"time"
ice "shylinux.com/x/icebergs"
- "shylinux.com/x/icebergs/base/cli"
"shylinux.com/x/icebergs/base/mdb"
kit "shylinux.com/x/toolkits"
)
-func _timer_action(m *ice.Message, arg ...string) {
- now := time.Now().UnixNano()
- m.OptionFields(m.Config(mdb.FIELD))
-
- m.Richs(TIMER, "", mdb.FOREACH, func(key string, value ice.Map) {
- if value = kit.GetMeta(value); value[cli.STATUS] == cli.STOP {
+func _timer_action(m *ice.Message, now time.Time, arg ...string) {
+ mdb.HashSelects(m).Tables(func(value ice.Maps) {
+ if value[mdb.COUNT] == "0" {
return
}
-
- order := kit.Int(value[ORDER])
- if n := kit.Time(kit.Format(value[NEXT])); now > n && order > 0 {
- m.Logs(TIMER, mdb.KEY, key, ORDER, order)
-
- msg := m.Cmd(value[ice.CMD])
- m.Grow(TIMER, kit.Keys(mdb.HASH, key), kit.Dict(ice.RES, msg.Result()))
- if value[ORDER] = kit.Format(order - 1); order > 1 {
- value[NEXT] = msg.Time(value[INTERVAL])
- }
+ if kit.Time(value[mdb.TIME]) > kit.Int64(now) {
+ return
}
+ m.Cmd(ROUTINE, mdb.CREATE, mdb.NAME, "some", kit.Keycb(ROUTINE), value[ice.CMD])
+ mdb.HashModify(m, mdb.HASH, value[mdb.HASH], mdb.COUNT, kit.Int(value[mdb.COUNT])-1, mdb.TIME, m.Time(value[INTERVAL]))
})
}
const (
DELAY = "delay"
INTERVAL = "interval"
- ORDER = "order"
- NEXT = "next"
TICK = "tick"
)
const TIMER = "timer"
func init() {
- Index.Merge(&ice.Context{Configs: ice.Configs{
- TIMER: {Name: TIMER, Help: "定时器", Value: kit.Data(
- mdb.FIELD, "time,hash,delay,interval,order,next,cmd", TICK, "1s",
- )},
- }, Commands: ice.Commands{
- TIMER: {Name: "timer hash id auto create action prunes", Help: "定时器", Actions: ice.MergeAction(ice.Actions{
- mdb.CREATE: {Name: "create delay=10ms interval=10s order=3 cmd=runtime", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
- m.Cmdy(mdb.INSERT, TIMER, "", mdb.HASH, DELAY, "10ms", INTERVAL, "10m", ORDER, 1, NEXT, m.Time(m.Option(DELAY)), arg)
- }},
+ Index.MergeCommands(ice.Commands{
+ TIMER: {Name: "timer hash auto create prunes", Help: "定时器", Actions: ice.MergeAction(ice.Actions{
+ mdb.CREATE: {Name: "create name=hi delay=10ms interval=10s count=3 cmd=runtime", Help: "创建"},
mdb.PRUNES: {Name: "prunes", Help: "清理", Hand: func(m *ice.Message, arg ...string) {
- m.OptionFields(m.Config(mdb.FIELD))
- m.Cmdy(mdb.PRUNES, TIMER, "", mdb.HASH, ORDER, 0)
+ mdb.HashPrunesValue(m, mdb.COUNT, "0")
}},
HAPPEN: {Name: "happen", Help: "执行", Hand: func(m *ice.Message, arg ...string) {
- _timer_action(m, arg...)
+ _timer_action(m, time.Now(), arg...)
}},
- }, mdb.ZoneAction()), Hand: func(m *ice.Message, arg ...string) {
- m.Fields(len(arg), m.Config(mdb.FIELD), "time,id,res")
- mdb.ZoneSelect(m, arg...)
- }},
- }})
+ RESTART: {Name: "restart count=3", Help: "重启", Hand: func(m *ice.Message, arg ...string) {
+ mdb.HashModify(m, m.OptionSimple(mdb.HashShort(m)), arg)
+ }},
+ }, mdb.HashAction(mdb.FIELD, "time,hash,name,delay,interval,count,cmd", TICK, "10s"))},
+ })
}
diff --git a/base/lex/matrix.go b/base/lex/matrix.go
index 7a66c443..3b81cb4b 100644
--- a/base/lex/matrix.go
+++ b/base/lex/matrix.go
@@ -385,9 +385,7 @@ const (
const MATRIX = "matrix"
func init() {
- Index.Merge(&ice.Context{Configs: ice.Configs{
- MATRIX: {Name: MATRIX, Help: "魔方矩阵", Value: kit.Data()},
- }, Commands: ice.Commands{
+ Index.MergeCommands(ice.Commands{
MATRIX: {Name: "matrix hash npage text auto", Help: "魔方矩阵", Actions: ice.Actions{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
// _lex_load(m.Load())
@@ -399,7 +397,7 @@ func init() {
case func(string, *Matrix):
cb(h, mat)
default:
- m.Error(true, ice.ErrNotImplement)
+ m.ErrorNotImplement(cb)
}
m.Echo(h)
}},
@@ -538,5 +536,5 @@ func init() {
m.Push("word", string(word))
})
}},
- }})
+ })
}
diff --git a/base/lex/regexp.go b/base/lex/regexp.go
index 2fb1c441..983e24fb 100644
--- a/base/lex/regexp.go
+++ b/base/lex/regexp.go
@@ -1,3 +1,4 @@
package lex
const REGEXP = "regexp"
+const PREFIX = "prefix"
diff --git a/base/lex/split.go b/base/lex/split.go
index c24c6fbc..289d9c70 100644
--- a/base/lex/split.go
+++ b/base/lex/split.go
@@ -4,6 +4,7 @@ import (
"strings"
ice "shylinux.com/x/icebergs"
+ "shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/nfs"
kit "shylinux.com/x/toolkits"
)
@@ -34,18 +35,17 @@ func _split_deep(stack []int, text string) ([]int, int) {
func _split_list(m *ice.Message, file string, arg ...string) ice.Map {
const DEEP = "_deep"
stack, deep := []int{}, 0
- list := kit.List(kit.Data(DEEP, -1))
- line := ""
+ list, line := kit.List(kit.Data(DEEP, -1)), ""
m.Cmd(nfs.CAT, file, func(text string) {
- if strings.HasPrefix(strings.TrimSpace(text), "# ") {
- return // 注释
- }
if strings.TrimSpace(text) == "" {
return // 空行
}
if line += text; strings.Count(text, "`")%2 == 1 {
return // 多行
}
+ if strings.HasPrefix(strings.TrimSpace(text), "# ") {
+ return // 注释
+ }
stack, deep = _split_deep(stack, text)
data := kit.Data(DEEP, deep)
@@ -61,8 +61,9 @@ func _split_list(m *ice.Message, file string, arg ...string) ice.Map {
ls = cb(ls, data)
case func([]string):
cb(ls)
+ case nil:
default:
- m.Error(true, ice.ErrNotImplement)
+ m.ErrorNotImplement(cb)
}
// 参数字段
@@ -80,7 +81,7 @@ func _split_list(m *ice.Message, file string, arg ...string) ice.Map {
// 查找节点
for i := len(list) - 1; i >= 0; i-- {
if deep > kit.Int(kit.Value(list[i], kit.Keym(DEEP))) {
- kit.Value(list[i], "list.-2", data)
+ kit.Value(list[i], kit.Keys(mdb.LIST, "-2"), data)
list = append(list, data)
break
}
@@ -90,9 +91,6 @@ func _split_list(m *ice.Message, file string, arg ...string) ice.Map {
})
return list[0].(ice.Map)
}
-func Split(m *ice.Message, arg ...string) ice.Map {
- return kit.Value(_split_list(m, arg[0], arg[1:]...), "list.0").(ice.Map)
-}
const (
SPLIT_SPACE = "split.space"
@@ -103,17 +101,17 @@ const (
const SPLIT = "split"
func init() {
- Index.Merge(&ice.Context{Configs: ice.Configs{
- SPLIT: {Name: "split", Help: "解析", Value: kit.Data()},
- }, Commands: ice.Commands{
- SPLIT: {Name: "split path key auto", Help: "解析", Hand: func(m *ice.Message, arg ...string) {
+ Index.MergeCommands(ice.Commands{
+ SPLIT: {Name: "split path key auto", Help: "分词", Hand: func(m *ice.Message, arg ...string) {
if len(arg) == 0 || strings.HasSuffix(arg[0], ice.PS) {
m.Cmdy(nfs.DIR, arg)
return
}
-
- m.Echo(kit.Format(_split_list(m, arg[0], kit.Split(kit.Join(arg[1:]))...)))
- m.DisplayStoryJSON()
+ m.Echo(kit.Format(_split_list(m, arg[0], kit.Split(kit.Join(arg[1:]))...))).DisplayStoryJSON()
}},
- }})
+ })
+}
+
+func Split(m *ice.Message, arg ...string) ice.Map {
+ return kit.Value(_split_list(m, arg[0], arg[1:]...), kit.Keys(mdb.LIST, "0")).(ice.Map)
}
diff --git a/base/log/log.go b/base/log/log.go
index d2f9cc68..68fa68f6 100644
--- a/base/log/log.go
+++ b/base/log/log.go
@@ -2,6 +2,7 @@ package log
import (
"bufio"
+ "os"
"path"
"strings"
@@ -9,7 +10,7 @@ import (
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/nfs"
kit "shylinux.com/x/toolkits"
- log "shylinux.com/x/toolkits/logs"
+ "shylinux.com/x/toolkits/logs"
)
type Log struct {
@@ -25,6 +26,13 @@ func (f *Frame) Spawn(m *ice.Message, c *ice.Context, arg ...string) ice.Server
return &Frame{}
}
func (f *Frame) Begin(m *ice.Message, arg ...string) ice.Server {
+ switch strings.Split(os.Getenv("TERM"), "-")[0] {
+ case "xterm", "screen":
+ ice.Info.Colors = true
+ default:
+ ice.Info.Colors = false
+ }
+
f.p = make(chan *Log, ice.MOD_BUFS)
ice.Info.Log = func(msg *ice.Message, p, l, s string) {
f.p <- &Log{m: msg, p: p, l: l, s: s}
@@ -36,7 +44,7 @@ func (f *Frame) Start(m *ice.Message, arg ...string) bool {
select {
case l, ok := <-f.p:
if !ok {
- break
+ return true
}
file := kit.Select(BENCH, m.Conf(SHOW, kit.Keys(l.l, FILE)))
@@ -124,9 +132,6 @@ var Index = &ice.Context{Name: "log", Help: "日志模块", Configs: ice.Configs
SHOW: {Name: SHOW, Help: "日志分流", Value: kit.Dict()},
}, Commands: ice.Commands{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
- if log.LogDisable {
- return // 禁用日志
- }
if !strings.Contains(ice.Getenv("ctx_daemon"), "log") {
return // 没有日志
}
@@ -140,7 +145,7 @@ var Index = &ice.Context{Name: "log", Help: "日志模块", Configs: ice.Configs
m.Conf(SHOW, kit.Keys(k, FILE), key)
})
// 日志文件
- if f, p, e := kit.Create(kit.Format(value[nfs.PATH])); m.Assert(e) {
+ if f, p, e := logs.CreateFile(kit.Format(value[nfs.PATH])); m.Assert(e) {
m.Cap(ice.CTX_STREAM, path.Base(p))
value[FILE] = bufio.NewWriter(f)
m.Log_CREATE(nfs.FILE, p)
diff --git a/base/mdb/engine.go b/base/mdb/engine.go
index 722cf75c..a55f50dc 100644
--- a/base/mdb/engine.go
+++ b/base/mdb/engine.go
@@ -2,31 +2,10 @@ package mdb
import (
ice "shylinux.com/x/icebergs"
- kit "shylinux.com/x/toolkits"
)
const ENGINE = "engine"
func init() {
- Index.Merge(&ice.Context{Configs: ice.Configs{
- ENGINE: {Name: ENGINE, Help: "引擎", Value: kit.Data(SHORT, TYPE, FIELD, "time,type,name,text")},
- }, Commands: ice.Commands{
- ENGINE: {Name: "engine type name text auto", Help: "引擎", Actions: ice.MergeAction(ice.Actions{
- CREATE: {Name: "create type name text", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
- m.Option(NAME, kit.Select(m.Option(TYPE), m.Option(NAME)))
- m.Option(TYPE, kit.Ext(m.Option(TYPE)))
- m.Cmdy(INSERT, m.PrefixKey(), "", HASH, m.OptionSimple("type,name,text"))
- }},
- }, HashAction()), Hand: func(m *ice.Message, arg ...string) {
- if len(arg) > 1 {
- m.Cmdy(SELECT, m.PrefixKey(), "", HASH, m.Config(SHORT), arg, func(value ice.Map) {
- m.Cmdy(kit.Keys(value[TEXT], value[NAME]), m.CommandKey(), arg[0], arg[1], kit.Select("", arg, 2), kit.Slice(arg, 3))
- })
- return
- }
- if HashSelect(m, arg...); len(arg) == 0 {
- m.Sort(TYPE)
- }
- }},
- }})
+ Index.MergeCommands(ice.Commands{ENGINE: {Name: "engine type name text auto", Help: "引擎", Actions: RenderAction()}})
}
diff --git a/base/mdb/hash.go b/base/mdb/hash.go
index 4ce26d1f..36bd0419 100644
--- a/base/mdb/hash.go
+++ b/base/mdb/hash.go
@@ -2,27 +2,34 @@ package mdb
import (
"encoding/json"
- "os"
"path"
- "strings"
ice "shylinux.com/x/icebergs"
kit "shylinux.com/x/toolkits"
+ "shylinux.com/x/toolkits/miss"
)
func _hash_fields(m *ice.Message) []string {
- return kit.Split(kit.Select("time,hash,type,name,text", m.OptionFields()))
+ return kit.Split(kit.Select(HASH_FIELD, m.OptionFields()))
+}
+func _hash_select_fields(m *ice.Message, prefix, chain string, key string, field string) (value string) {
+ defer m.RLock(prefix, chain)()
+ m.Richs(prefix, chain, key, func(h string, v Map) {
+ if field == HASH {
+ value = h
+ } else {
+ value = kit.Format(v[field])
+ }
+ })
+ return
}
func _hash_inputs(m *ice.Message, prefix, chain string, field, value string) {
defer m.RLock(prefix, chain)()
list := map[string]int{}
- m.Richs(prefix, chain, FOREACH, func(key string, val ice.Map) {
- if val = kit.GetMeta(val); kit.Format(val[COUNT]) != "" {
- list[kit.Format(val[field])] = kit.Int(val[COUNT])
- } else {
- list[kit.Format(val[field])]++
- }
+ m.Richs(prefix, chain, FOREACH, func(val Map) {
+ val = kit.GetMeta(val)
+ list[kit.Format(val[field])] += kit.Int(kit.Select("1", val[COUNT]))
})
for k, i := range list {
m.Push(field, k)
@@ -30,18 +37,30 @@ func _hash_inputs(m *ice.Message, prefix, chain string, field, value string) {
}
m.SortIntR(COUNT)
}
-func _hash_insert(m *ice.Message, prefix, chain string, arg ...string) {
+func _hash_insert(m *ice.Message, prefix, chain string, arg ...string) string {
defer m.Lock(prefix, chain)()
- if m.Option(ice.MSG_DOMAIN) != "" {
- m.Conf(prefix, kit.Keys(chain, kit.Keym(SHORT)), m.Conf(prefix, kit.Keym(SHORT)))
+ if value := m.Confm(prefix, kit.Keys(HASH, arg[1])); value != nil {
+ value = kit.GetMeta(value)
+ for i := 2; i < len(arg)-1; i += 2 {
+ kit.Value(value, arg[i], arg[i+1])
+ }
+ return arg[1]
}
+
m.Log_INSERT(KEY, path.Join(prefix, chain), arg[0], arg[1])
if expire := m.Conf(prefix, kit.Keys(chain, kit.Keym(EXPIRE))); expire != "" {
arg = kit.Simple(TIME, m.Time(expire), arg)
}
-
- m.Echo(m.Rich(prefix, chain, kit.Data(arg)))
+ if m.Option(ice.MSG_DOMAIN) != "" {
+ m.Conf(prefix, kit.Keys(chain, kit.Keym(SHORT)), m.Conf(prefix, kit.Keym(SHORT)))
+ }
+ if m.Optionv(TARGET) != nil {
+ m.Echo(m.Rich(prefix, chain, kit.Data(arg, TARGET, m.Optionv(TARGET))))
+ } else {
+ m.Echo(m.Rich(prefix, chain, kit.Data(arg)))
+ }
+ return m.Result()
}
func _hash_delete(m *ice.Message, prefix, chain, field, value string) {
defer m.Lock(prefix, chain)()
@@ -49,7 +68,7 @@ func _hash_delete(m *ice.Message, prefix, chain, field, value string) {
if field != HASH {
field, value = HASH, kit.Select(kit.Hashs(value), m.Option(HASH))
}
- m.Richs(prefix, chain, value, func(key string, val ice.Map) {
+ m.Richs(prefix, chain, value, func(key string, val Map) {
m.Log_DELETE(KEY, path.Join(prefix, chain), field, value, VALUE, kit.Format(val))
m.Conf(prefix, kit.Keys(chain, HASH, key), "")
})
@@ -57,15 +76,9 @@ func _hash_delete(m *ice.Message, prefix, chain, field, value string) {
func _hash_modify(m *ice.Message, prefix, chain string, field, value string, arg ...string) {
defer m.Lock(prefix, chain)()
- m.Richs(prefix, chain, value, func(key string, val ice.Map) {
- val = kit.GetMeta(val)
+ m.Richs(prefix, chain, value, func(key string, val Map) {
m.Log_MODIFY(KEY, path.Join(prefix, chain), field, value, arg)
- for i := 0; i < len(arg); i += 2 {
- if arg[i] == field {
- continue
- }
- kit.Value(val, arg[i], kit.Select("", arg, i+1))
- }
+ _mdb_modify(m, val, field, arg...)
})
}
func _hash_select(m *ice.Message, prefix, chain, field, value string) {
@@ -75,19 +88,8 @@ func _hash_select(m *ice.Message, prefix, chain, field, value string) {
value = RANDOMS
}
fields := _hash_fields(m)
- m.Richs(prefix, chain, value, func(key string, val ice.Map) {
- switch val = kit.GetMeta(val); cb := m.OptionCB(SELECT).(type) {
- case func(fields []string, value ice.Map):
- cb(fields, val)
- case func(value ice.Map):
- cb(val)
- default:
- if m.OptionFields() == DETAIL {
- m.Push(DETAIL, val)
- } else {
- m.Push(key, val, fields)
- }
- }
+ m.Richs(prefix, chain, value, func(key string, value Map) {
+ _mdb_select(m, key, value, fields, nil)
})
if !m.FieldsIsDetail() {
m.SortTimeR(TIME)
@@ -97,9 +99,9 @@ func _hash_prunes(m *ice.Message, prefix, chain string, arg ...string) {
defer m.RLock(prefix, chain)()
fields := _hash_fields(m)
- m.Richs(prefix, chain, FOREACH, func(key string, val ice.Map) {
+ m.Richs(prefix, chain, FOREACH, func(key string, val Map) {
switch val = kit.GetMeta(val); cb := m.OptionCB(PRUNES).(type) {
- case func(string, ice.Map) bool:
+ case func(string, Map) bool:
if !cb(key, val) {
return
}
@@ -116,7 +118,7 @@ func _hash_prunes(m *ice.Message, prefix, chain string, arg ...string) {
func _hash_export(m *ice.Message, prefix, chain, file string) {
defer m.Lock(prefix, chain)()
- f, p, e := kit.Create(kit.Keys(file, JSON))
+ f, p, e := miss.CreateFile(kit.Keys(file, JSON))
m.Assert(e)
defer f.Close()
@@ -131,13 +133,11 @@ func _hash_export(m *ice.Message, prefix, chain, file string) {
func _hash_import(m *ice.Message, prefix, chain, file string) {
defer m.Lock(prefix, chain)()
- f, e := os.Open(kit.Keys(file, JSON))
- if m.Warn(e) {
- return
- }
+ f, e := miss.OpenFile(kit.Keys(file, JSON))
+ m.Assert(e)
defer f.Close()
- list := ice.Map{}
+ list := Map{}
m.Assert(json.NewDecoder(f).Decode(&list))
count := 0
@@ -157,41 +157,12 @@ func _hash_import(m *ice.Message, prefix, chain, file string) {
m.Echo("%d", count)
}
+const (
+ HASH_FIELD = "time,hash,type,name,text"
+)
const HASH = "hash"
-func AutoConfig(args ...ice.Any) *ice.Action {
- return &ice.Action{Hand: func(m *ice.Message, arg ...string) {
- if cs := m.Target().Configs; cs[m.CommandKey()] == nil && len(args) > 0 {
- cs[m.CommandKey()] = &ice.Config{Value: kit.Data(args...)}
- m.Load(m.CommandKey())
- }
-
- inputs := []ice.Any{}
- kit.Fetch(kit.Split(m.Config(FIELD)), func(i int, k string) {
- switch k {
- case TIME, HASH, ID:
- return
- }
- inputs = append(inputs, k)
- })
-
- cs := m.Target().Commands
- if cs[m.CommandKey()] == nil {
- return
- }
-
- if cs[m.CommandKey()].Actions[INSERT] != nil {
- if cs[m.CommandKey()].Meta[INSERT] == nil {
- m.Design(INSERT, "添加", append([]ice.Any{ZONE}, inputs...)...)
- }
- } else if cs[m.CommandKey()].Actions[CREATE] != nil {
- if cs[m.CommandKey()].Meta[CREATE] == nil {
- m.Design(CREATE, "创建", inputs...)
- }
- }
- }}
-}
-func HashAction(args ...ice.Any) ice.Actions {
+func HashAction(args ...Any) ice.Actions {
return ice.Actions{ice.CTX_INIT: AutoConfig(args...),
INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) { HashInputs(m, arg) }},
CREATE: {Name: "create", Help: "创建", Hand: func(m *ice.Message, arg ...string) { HashCreate(m, arg) }},
@@ -203,93 +174,149 @@ func HashAction(args ...ice.Any) ice.Actions {
IMPORT: {Name: "import", Help: "导入", Hand: func(m *ice.Message, arg ...string) { HashImport(m, arg) }},
}
}
-func HashActionStatus(args ...ice.Any) ice.Actions {
+func HashActionStatus(args ...Any) ice.Actions {
list := HashAction(args...)
list[PRUNES] = &ice.Action{Name: "prunes", Help: "清理", Hand: func(m *ice.Message, arg ...string) {
m.OptionFields(m.Config(FIELD))
- m.Cmdy(PRUNES, m.PrefixKey(), "", HASH, STATUS, "error")
- m.Cmdy(PRUNES, m.PrefixKey(), "", HASH, STATUS, "close")
+ m.Cmdy(PRUNES, m.PrefixKey(), "", HASH, STATUS, ice.ERROR)
+ m.Cmdy(PRUNES, m.PrefixKey(), "", HASH, STATUS, ice.CLOSE)
+ m.Cmdy(PRUNES, m.PrefixKey(), "", HASH, STATUS, ice.STOP)
+ m.Cmdy(PRUNES, m.PrefixKey(), "", HASH, STATUS, ice.END)
+ m.Tables(func(value ice.Maps) { HashRemove(m, HASH, value[HASH]) })
}}
return list
}
-func HashInputs(m *ice.Message, arg ...ice.Any) *ice.Message {
- return m.Cmdy(INPUTS, m.PrefixKey(), "", HASH, kit.Simple(arg...))
+func HashShort(m *ice.Message) string {
+ return kit.Select(HASH, m.Config(SHORT), m.Config(SHORT) != UNIQ)
}
-func HashCreate(m *ice.Message, arg ...ice.Any) *ice.Message {
- field := m.Config(FIELD)
- args := kit.Simple(arg...)
- for i := 0; i < len(args); i += 2 {
- if !strings.Contains(field, args[i]) {
- args[i] = kit.Keys("extra", args[i])
- }
- }
- return m.Cmdy(INSERT, m.PrefixKey(), "", HASH, args)
+func HashField(m *ice.Message) string { return kit.Select(HASH_FIELD, m.Config(FIELD)) }
+func HashArgs(m *ice.Message, arg ...Any) []string {
+ return _mdb_args(m, HashField(m), arg...)
}
-func HashRemove(m *ice.Message, arg ...ice.Any) *ice.Message {
- m.OptionFields(m.Config(FIELD))
- defer m.Event(kit.Keys(m.CommandKey(), REMOVE), m.CommandKey(), m.Option(m.Config(SHORT)))
- return m.Cmd(DELETE, m.PrefixKey(), "", HASH, kit.Simple(arg...))
+func HashInputs(m *ice.Message, arg ...Any) *ice.Message {
+ return m.Cmdy(INPUTS, m.PrefixKey(), "", HASH, HashArgs(m, arg))
}
-func HashModify(m *ice.Message, arg ...ice.Any) *ice.Message {
- field := m.Config(FIELD)
- args := kit.Simple(arg...)
- for i := 0; i < len(args); i += 2 {
- if !strings.Contains(field, args[i]) {
- args[i] = kit.Keys("extra", args[i])
- }
- }
- return m.Cmd(MODIFY, m.PrefixKey(), "", HASH, args)
+func HashCreate(m *ice.Message, arg ...Any) *ice.Message {
+ return m.Cmdy(INSERT, m.PrefixKey(), "", HASH, HashArgs(m, arg...))
+}
+func HashRemove(m *ice.Message, arg ...Any) *ice.Message {
+ return m.Cmdy(DELETE, m.PrefixKey(), "", HASH, m.OptionSimple(HashShort(m)), arg)
+}
+func HashModify(m *ice.Message, arg ...Any) *ice.Message {
+ return m.Cmd(MODIFY, m.PrefixKey(), "", HASH, m.OptionSimple(HashShort(m)), HashArgs(m, arg...))
}
func HashSelect(m *ice.Message, arg ...string) *ice.Message {
- m.Fields(len(arg), m.Config(FIELD))
- m.Cmdy(SELECT, m.PrefixKey(), "", HASH, m.Config(SHORT), arg)
- m.PushAction(m.Config("action"), REMOVE)
- m.StatusTimeCount()
- return m
-}
-func HashPrunes(m *ice.Message, cb func(ice.Maps) bool) *ice.Message {
- _key := func(m *ice.Message) string {
- if m.Config(HASH) == UNIQ {
- return HASH
- }
- if m.Config(SHORT) == UNIQ {
- return HASH
- }
- return kit.Select(HASH, m.Config(SHORT))
+ m.Fields(len(kit.Slice(arg, 0, 1)), HashField(m))
+ m.Cmdy(SELECT, m.PrefixKey(), "", HASH, HashShort(m), arg)
+ if m.PushAction(m.Config(ACTION), REMOVE); !m.FieldsIsDetail() {
+ return m.StatusTimeCount()
+ } else {
+ return m.StatusTime()
}
+}
+func HashPrunes(m *ice.Message, cb func(Maps) bool) *ice.Message {
expire := kit.Time(kit.Select(m.Time("-72h"), m.Option(EXPIRE)))
- m.Cmd(m.CommandKey()).Tables(func(value ice.Maps) {
- if kit.Time(value[TIME]) > expire {
- return
+ m.Cmd(m.CommandKey()).Tables(func(value Maps) {
+ if cb != nil && !cb(value) || kit.Time(value[TIME]) < expire {
+ HashRemove(m, HashShort(m), value[HashShort(m)])
}
- if cb != nil && cb(value) {
- return
- }
- m.OptionFields(m.Config(FIELD))
- m.Cmdy(DELETE, m.PrefixKey(), "", HASH, _key(m), value[_key(m)])
})
return m
}
-func HashExport(m *ice.Message, arg ...ice.Any) *ice.Message {
- m.OptionFields(m.Config(FIELD))
- return m.Cmd(EXPORT, m.PrefixKey(), "", HASH, kit.Simple(arg...))
+func HashExport(m *ice.Message, arg ...Any) *ice.Message {
+ return m.Cmdy(EXPORT, m.PrefixKey(), "", HASH, arg)
}
-func HashImport(m *ice.Message, arg ...ice.Any) *ice.Message {
- return m.Cmd(IMPORT, m.PrefixKey(), "", HASH, kit.Simple(arg...))
+func HashImport(m *ice.Message, arg ...Any) *ice.Message {
+ return m.Cmdy(IMPORT, m.PrefixKey(), "", HASH, arg)
}
-func HashCache(m *ice.Message, h string, add func() ice.Any) ice.Any {
+func HashTarget(m *ice.Message, h string, add func() Any) Any {
defer m.Lock()()
- p := m.Confv(m.PrefixKey(), kit.Keys(HASH, h, "_cache"))
- if pp, ok := p.(ice.Map); ok && len(pp) == 0 {
+ p := m.Confv(m.PrefixKey(), kit.Keys(HASH, h, TARGET))
+ if pp, ok := p.(Map); ok && len(pp) == 0 {
p = nil
}
- if add != nil && p == nil {
+ if p == nil && add != nil {
p = add()
- m.Confv(m.PrefixKey(), kit.Keys(HASH, h, "_cache"), p) // 添加
+ m.Confv(m.PrefixKey(), kit.Keys(HASH, h, TARGET), p)
}
return p
}
+func HashPrunesValue(m *ice.Message, field, value string) {
+ m.OptionFields(m.Config(FIELD))
+ m.Cmdy(PRUNES, m.PrefixKey(), "", HASH, field, value)
+}
+func HashSelectFields(m *ice.Message, key string, field string) (value string) {
+ HashSelectDetail(m, key, func(h string, val ice.Map) {
+ if field == HASH {
+ value = h
+ } else {
+ value = kit.Format(val[field])
+ }
+ })
+ return
+}
+func HashSelectDetail(m *ice.Message, key string, cb Any) bool {
+ defer m.RLock(m.PrefixKey(), "")()
+ has := false
+ m.Richs(m.PrefixKey(), nil, key, func(key string, value Map) {
+ hashSelect(m, key, value, cb)
+ has = true
+ })
+ return has
+}
+func HashSelectUpdate(m *ice.Message, key string, cb Any) *ice.Message {
+ defer m.Lock(m.PrefixKey(), "")()
+ m.Richs(m.PrefixKey(), nil, key, func(key string, value Map) {
+ hashSelect(m, key, value, cb)
+ })
+ return m
+}
+func HashSelectSearch(m *ice.Message, args []string, keys ...string) *ice.Message {
+ if len(keys) == 0 {
+ ls := kit.Split(m.Config(FIELD))
+ for _, k := range ls {
+ switch k {
+ case TIME, HASH:
+ default:
+ keys = append(keys, k)
+ }
+ }
+ }
+ if args[0] == m.CommandKey() {
+ HashSelectValue(m, func(value ice.Map) {
+ if args[1] == "" || args[1] == value[keys[1]] {
+ m.PushSearch(kit.SimpleKV("", value[keys[0]], value[keys[1]], value[keys[2]]), value)
+ }
+ })
+ }
+ return m
+}
+func HashSelectValue(m *ice.Message, cb Any) *ice.Message {
+ defer m.RLock(m.PrefixKey(), "")()
+ m.Richs(m.PrefixKey(), nil, FOREACH, func(key string, value Map) {
+ hashSelect(m, key, value, cb)
+ })
+ return m
+}
+func HashSelects(m *ice.Message, arg ...string) *ice.Message {
+ m.OptionFields(m.Config(FIELD))
+ return HashSelect(m, arg...)
+}
+func hashSelect(m *ice.Message, key string, value Map, cb Any) *ice.Message {
+ switch value = kit.GetMeta(value); cb := cb.(type) {
+ case func(string, Map):
+ cb(key, value)
+ case func(Map):
+ cb(value)
+ case func(Any):
+ cb(value[TARGET])
+ case nil:
+ default:
+ m.ErrorNotImplement(cb)
+ }
+ return m
+}
diff --git a/base/mdb/list.go b/base/mdb/list.go
index 98a30e92..6491e168 100644
--- a/base/mdb/list.go
+++ b/base/mdb/list.go
@@ -2,24 +2,23 @@ package mdb
import (
"encoding/csv"
- "os"
"path"
ice "shylinux.com/x/icebergs"
kit "shylinux.com/x/toolkits"
+ "shylinux.com/x/toolkits/miss"
)
func _list_fields(m *ice.Message) []string {
- return kit.Split(kit.Select("time,id,type,name,text", m.OptionFields()))
+ return kit.Split(kit.Select(LIST_FIELD, m.OptionFields()))
}
func _list_inputs(m *ice.Message, prefix, chain string, field, value string) {
+ defer m.RLock(prefix, chain)()
+
list := map[string]int{}
- m.Grows(prefix, chain, "", "", func(index int, val ice.Map) {
- if val = kit.GetMeta(val); kit.Format(val[COUNT]) != "" {
- list[kit.Format(val[field])] = kit.Int(val[COUNT])
- } else {
- list[kit.Format(val[field])]++
- }
+ m.Grows(prefix, chain, "", "", func(val ice.Map) {
+ val = kit.GetMeta(val)
+ list[kit.Format(val[field])] += kit.Int(kit.Select("1", val[COUNT]))
})
for k, i := range list {
m.Push(field, k)
@@ -28,43 +27,34 @@ func _list_inputs(m *ice.Message, prefix, chain string, field, value string) {
m.SortIntR(COUNT)
}
func _list_insert(m *ice.Message, prefix, chain string, arg ...string) {
+ defer m.Lock(prefix, chain)()
+
m.Log_INSERT(KEY, path.Join(prefix, chain), arg[0], arg[1])
m.Echo("%d", m.Grow(prefix, chain, kit.Dict(arg)))
}
-func _list_delete(m *ice.Message, prefix, chain, field, value string) {
-}
func _list_modify(m *ice.Message, prefix, chain string, field, value string, arg ...string) {
+ defer m.Lock(prefix, chain)()
+
m.Grows(prefix, chain, field, value, func(index int, val ice.Map) {
- val = kit.GetMeta(val)
m.Log_MODIFY(KEY, path.Join(prefix, chain), field, value, arg)
- for i := 0; i < len(arg); i += 2 {
- if arg[i] == field {
- continue
- }
- kit.Value(val, arg[i], kit.Select("", arg, i+1))
- }
+ _mdb_modify(m, val, field, arg...)
})
}
func _list_select(m *ice.Message, prefix, chain, field, value string) {
+ defer m.RLock(prefix, chain)()
+
if value == "" {
field = ""
}
fields := _list_fields(m)
- m.Grows(prefix, chain, kit.Select(m.Option(ice.CACHE_FIELD), field), kit.Select(m.Option(ice.CACHE_VALUE), value), func(index int, val ice.Map) {
- switch val = kit.GetMeta(val); cb := m.OptionCB(SELECT).(type) {
- case func(fields []string, value ice.Map):
- cb(fields, val)
- default:
- if m.OptionFields() == DETAIL {
- m.Push(DETAIL, val)
- } else {
- m.Push("", val, fields)
- }
- }
+ m.Grows(prefix, chain, kit.Select(m.Option(ice.CACHE_FIELD), field), kit.Select(m.Option(ice.CACHE_VALUE), value), func(value ice.Map) {
+ _mdb_select(m, "", value, fields, nil)
})
}
func _list_export(m *ice.Message, prefix, chain, file string) {
- f, p, e := kit.Create(kit.Keys(file, CSV))
+ defer m.RLock(prefix, chain)()
+
+ f, p, e := miss.CreateFile(kit.Keys(file, CSV))
m.Assert(e)
defer f.Close()
@@ -72,7 +62,7 @@ func _list_export(m *ice.Message, prefix, chain, file string) {
defer w.Flush()
count := 0
- head := kit.Split(m.OptionFields())
+ head := kit.Split(m.Config(FIELD))
m.Grows(prefix, chain, "", "", func(index int, val ice.Map) {
if val = kit.GetMeta(val); index == 0 {
if len(head) == 0 || head[0] == ice.CACHE_DETAIL { // 默认表头
@@ -98,7 +88,9 @@ func _list_export(m *ice.Message, prefix, chain, file string) {
m.Echo(p)
}
func _list_import(m *ice.Message, prefix, chain, file string) {
- f, e := os.Open(kit.Keys(file, CSV))
+ defer m.RLock(prefix, chain)()
+
+ f, e := miss.OpenFile(kit.Keys(file, CSV))
m.Assert(e)
defer f.Close()
@@ -128,55 +120,102 @@ func _list_import(m *ice.Message, prefix, chain, file string) {
m.Log_IMPORT(KEY, kit.Keys(prefix, chain), COUNT, count)
m.Echo("%d", count)
}
-func _list_prunes(m *ice.Message, prefix, chain string, arg ...string) {
-}
+const (
+ LIST_FIELD = "time,id,type,name,text"
+)
const LIST = "list"
func ListAction(args ...ice.Any) ice.Actions {
return ice.Actions{ice.CTX_INIT: AutoConfig(args...),
INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) {
- m.Cmdy(INPUTS, m.PrefixKey(), "", LIST, arg)
+ m.Cmdy(INPUTS, m.PrefixKey(), "", LIST, ListArgs(m, arg))
}},
- INSERT: {Name: "insert type=go name=hi text=hello", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
- m.Cmdy(INSERT, m.PrefixKey(), "", LIST, arg)
+ INSERT: {Name: "insert", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
+ m.Cmdy(INSERT, m.PrefixKey(), "", LIST, ListArgs(m, arg))
}},
DELETE: {Name: "delete", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(DELETE, m.PrefixKey(), "", LIST, m.OptionSimple(ID), arg)
}},
MODIFY: {Name: "modify", Help: "编辑", Hand: func(m *ice.Message, arg ...string) {
- m.Cmdy(MODIFY, m.PrefixKey(), "", LIST, m.OptionSimple(ID), arg)
+ m.Cmdy(MODIFY, m.PrefixKey(), "", LIST, m.OptionSimple(ID), ListArgs(m, arg))
}},
- EXPORT: {Name: "export", Help: "导出", Hand: func(m *ice.Message, arg ...string) {
- m.Option(ice.CACHE_LIMIT, "-1")
- m.OptionFields(m.Config(FIELD))
- m.Cmdy(EXPORT, m.PrefixKey(), "", LIST)
- m.Conf(m.PrefixKey(), LIST, "")
- m.Config(COUNT, 0)
- }},
- IMPORT: {Name: "import", Help: "导入", Hand: func(m *ice.Message, arg ...string) {
- m.Cmdy(IMPORT, m.PrefixKey(), "", LIST, arg)
+ SELECT: {Name: "select", Help: "列表", Hand: func(m *ice.Message, arg ...string) {
+ ListSelect(m, arg...)
}},
PRUNES: {Name: "prunes", Help: "清理", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(PRUNES, m.PrefixKey(), "", LIST, arg)
}},
+ EXPORT: {Name: "export", Help: "导出", Hand: func(m *ice.Message, arg ...string) {
+ m.Cmdy(EXPORT, m.PrefixKey(), "", LIST, arg)
+ }},
+ IMPORT: {Name: "import", Help: "导入", Hand: func(m *ice.Message, arg ...string) {
+ m.Cmdy(IMPORT, m.PrefixKey(), "", LIST, arg)
+ }},
PREV: {Name: "prev", Help: "上一页", Hand: func(m *ice.Message, arg ...string) {
PrevPage(m, m.Config(COUNT), kit.Slice(arg, 1)...)
}},
NEXT: {Name: "next", Help: "下一页", Hand: func(m *ice.Message, arg ...string) {
- NextPage(m, m.Config(COUNT), kit.Slice(arg, 1)...)
- }},
- SELECT: {Name: "select", Help: "列表", Hand: func(m *ice.Message, arg ...string) {
- ListSelect(m, arg...)
+ NextPageLimit(m, m.Config(COUNT), kit.Slice(arg, 1)...)
}},
}
}
+func ListField(m *ice.Message) string { return kit.Select(LIST_FIELD, m.Config(FIELD)) }
+func ListArgs(m *ice.Message, arg ...ice.Any) []string {
+ return _mdb_args(m, ListField(m), arg...)
+}
func ListSelect(m *ice.Message, arg ...string) *ice.Message {
m.OptionPage(kit.Slice(arg, 1)...)
- m.Fields(len(kit.Slice(arg, 0, 1)), m.Config(FIELD))
- m.Cmdy(SELECT, m.PrefixKey(), "", LIST, ID, arg)
- if !m.FieldsIsDetail() {
+ m.Fields(len(kit.Slice(arg, 0, 1)), ListField(m))
+ if m.Cmdy(SELECT, m.PrefixKey(), "", LIST, ID, arg); !m.FieldsIsDetail() {
m.StatusTimeCountTotal(m.Config(COUNT))
+ } else {
+ m.StatusTime()
}
return m
}
+func PrevPageLimit(m *ice.Message, total string, arg ...string) {
+ if kit.Int(kit.Select("0", arg, 1)) > 0 {
+ PrevPage(m, total, arg...)
+ } else {
+ m.Toast("已经是最前一页啦!")
+ m.ProcessHold()
+ }
+}
+func PrevPage(m *ice.Message, total string, arg ...string) {
+ limit, offend := kit.Select("10", arg, 0), kit.Select("0", arg, 1)
+ offends := kit.Int(offend) - kit.Int(limit)
+ if total != "0" && (offends <= -kit.Int(total) || offends >= kit.Int(total)) {
+ m.Toast("已经是最前一页啦!")
+ m.ProcessHold()
+ return
+ }
+ if offends == 0 {
+ m.ProcessRewrite("offend", "")
+ } else {
+ m.ProcessRewrite("offend", offends)
+ }
+
+}
+func NextPage(m *ice.Message, total string, arg ...string) {
+ limit, offend := kit.Select("10", arg, 0), kit.Select("0", arg, 1)
+ offends := kit.Int(offend) + kit.Int(limit)
+ if total != "0" && (offends <= -kit.Int(total) || offends >= kit.Int(total)) {
+ m.Toast("已经是最后一页啦!")
+ m.ProcessHold()
+ return
+ }
+ if offends == 0 {
+ m.ProcessRewrite("offend", "")
+ } else {
+ m.ProcessRewrite("offend", offends)
+ }
+}
+func NextPageLimit(m *ice.Message, total string, arg ...string) {
+ if kit.Int(kit.Select("0", arg, 1)) < 0 {
+ NextPage(m, total, arg...)
+ } else {
+ m.Toast("已经是最后一页啦!")
+ m.ProcessHold()
+ }
+}
diff --git a/base/mdb/mdb.go b/base/mdb/mdb.go
index 1048be94..2165f111 100644
--- a/base/mdb/mdb.go
+++ b/base/mdb/mdb.go
@@ -8,26 +8,73 @@ import (
kit "shylinux.com/x/toolkits"
)
+type Any = interface{}
+type Map = map[string]Any
+type Maps = map[string]string
+
+func _domain_chain(m *ice.Message, chain string) string {
+ return kit.Keys(m.Option(ice.MSG_DOMAIN), chain)
+}
func _file_name(m *ice.Message, arg ...string) string {
if len(arg) > 3 && strings.Contains(arg[3], ice.PS) {
return arg[3]
}
return path.Join(ice.USR_LOCAL_EXPORT, m.Option(ice.MSG_DOMAIN), path.Join(arg[:2]...), arg[2])
- return kit.Select(path.Join(ice.USR_LOCAL_EXPORT, m.Option(ice.MSG_DOMAIN), path.Join(arg[:2]...), arg[2]), arg, 3)
}
-func _domain_chain(m *ice.Message, chain string) string {
- return kit.Keys(m.Option(ice.MSG_DOMAIN), chain)
+func _mdb_args(m *ice.Message, field string, arg ...Any) []string {
+ args := kit.Simple(arg...)
+ for i := 0; i < len(args); i += 2 {
+ if !strings.Contains(field, args[i]) && !strings.HasPrefix(args[i], EXTRA) {
+ args[i] = kit.Keys(EXTRA, args[i])
+ }
+ }
+ return args
+}
+func _mdb_modify(m *ice.Message, val ice.Map, field string, arg ...string) {
+ val = kit.GetMeta(val)
+ for i := 0; i < len(arg); i += 2 {
+ if arg[i] == field {
+ continue
+ }
+ kit.Value(val, arg[i], kit.Select("", arg, i+1))
+ }
+}
+func _mdb_select(m *ice.Message, key string, value ice.Map, fields []string, val ice.Map) {
+ switch value = kit.GetMeta(value); cb := m.OptionCB(SELECT).(type) {
+ case func(string, []string, ice.Map, ice.Map):
+ cb(key, fields, value, val)
+ case func([]string, ice.Map):
+ cb(fields, value)
+ case func(string, ice.Map, ice.Map):
+ cb(key, value, val)
+ case func(string, ice.Map):
+ cb(key, value)
+ case func(ice.Map):
+ cb(value)
+ case func(Any):
+ cb(value[TARGET])
+ case func(ice.Maps):
+ res := ice.Maps{}
+ for k, v := range value {
+ res[k] = kit.Format(v)
+ }
+ cb(res)
+ case nil:
+ if m.FieldsIsDetail() {
+ m.Push(ice.CACHE_DETAIL, value)
+ } else {
+ m.Push(key, value, fields, val)
+ }
+ default:
+ m.ErrorNotImplement(cb)
+ }
}
-const (
- CSV = "csv"
- JSON = "json"
-)
const (
DICT = kit.MDB_DICT
META = kit.MDB_META
- UNIQ = kit.MDB_UNIQ
+ UNIQ = kit.MDB_UNIQ
FOREACH = kit.MDB_FOREACH
RANDOMS = kit.MDB_RANDOMS
)
@@ -36,7 +83,6 @@ const (
ID = kit.MDB_ID
KEY = kit.MDB_KEY
TIME = kit.MDB_TIME
- // ZONE = kit.MDB_ZONE
TYPE = kit.MDB_TYPE
NAME = kit.MDB_NAME
TEXT = kit.MDB_TEXT
@@ -71,6 +117,7 @@ const (
const (
DETAIL = "detail"
RANDOM = "random"
+ ACTION = "action"
INPUTS = "inputs"
CREATE = "create"
@@ -91,103 +138,70 @@ const (
PREV = "prev"
PAGE = "page"
OFFEND = "offend"
+
+ JSON = "json"
+ CSV = "csv"
)
const (
CACHE_CLEAR_ON_EXIT = "cache.clear.on.exit"
+
+ SOURCE = "_source"
+ TARGET = "_target"
)
-func PrevPageLimit(m *ice.Message, total string, arg ...string) {
- if kit.Int(kit.Select("0", arg, 1)) > 0 {
- PrevPage(m, total, arg...)
- } else {
- m.Toast("已经是最前一页啦!")
- m.ProcessHold()
- }
-}
-func PrevPage(m *ice.Message, total string, arg ...string) {
- limit, offend := kit.Select("10", arg, 0), kit.Select("0", arg, 1)
- offends := kit.Int(offend) - kit.Int(limit)
- if total != "0" && (offends <= -kit.Int(total) || offends >= kit.Int(total)) {
- m.Toast("已经是最前一页啦!")
- m.ProcessHold()
- return
- }
- if offends == 0 {
- m.ProcessRewrite("offend", "")
- } else {
- m.ProcessRewrite("offend", offends)
- }
-
-}
-func NextPage(m *ice.Message, total string, arg ...string) {
- limit, offend := kit.Select("10", arg, 0), kit.Select("0", arg, 1)
- offends := kit.Int(offend) + kit.Int(limit)
- if total != "0" && (offends <= -kit.Int(total) || offends >= kit.Int(total)) {
- m.Toast("已经是最后一页啦!")
- m.ProcessHold()
- return
- }
- if offends == 0 {
- m.ProcessRewrite("offend", "")
- } else {
- m.ProcessRewrite("offend", offends)
- }
-}
-func NextPageLimit(m *ice.Message, total string, arg ...string) {
- if kit.Int(kit.Select("0", arg, 1)) < 0 {
- NextPage(m, total, arg...)
- } else {
- m.Toast("已经是最后一页啦!")
- m.ProcessHold()
- }
-}
-
const MDB = "mdb"
var Index = &ice.Context{Name: MDB, Help: "数据模块", Commands: ice.Commands{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {}},
ice.CTX_EXIT: {Hand: func(m *ice.Message, arg ...string) {}},
INPUTS: {Name: "inputs key sub type field value", Help: "补全", Hand: func(m *ice.Message, arg ...string) {
- switch arg[3] {
+ switch arg[3] = strings.TrimPrefix(arg[3], "extra."); arg[3] {
+ case ice.POD:
+ m.Cmdy("route")
+ case ice.CTX:
+ m.Cmdy("context")
+ case ice.CMD:
+ m.Cmdy("context", kit.Select(m.Option(ice.CTX), m.Option(kit.Keys(EXTRA, ice.CTX))), "command")
case "index":
- m.OptionFields(arg[3])
- m.Cmdy("command", "search", "command", "", "")
- }
- switch arg[2] {
- case ZONE: // inputs key sub type zone field value
- _list_inputs(m, arg[0], _domain_chain(m, kit.Keys(arg[1], kit.KeyHash(arg[3]))), kit.Select(NAME, arg, 4), kit.Select("", arg, 5))
- case HASH:
- _hash_inputs(m, arg[0], _domain_chain(m, arg[1]), kit.Select(NAME, arg, 3), kit.Select("", arg, 4))
- case LIST:
- _list_inputs(m, arg[0], _domain_chain(m, arg[1]), kit.Select(NAME, arg, 3), kit.Select("", arg, 4))
+ m.OptionFields(arg[0])
+ m.Cmdy("command", SEARCH, "command", kit.Select("", arg, 1))
+ default:
+ switch arg[2] {
+ case ZONE: // inputs key sub type zone field value
+ _zone_inputs(m, arg[0], _domain_chain(m, arg[1]), arg[3], kit.Select(NAME, arg, 4), kit.Select("", arg, 5))
+ case HASH:
+ _hash_inputs(m, arg[0], _domain_chain(m, arg[1]), kit.Select(NAME, arg, 3), kit.Select("", arg, 4))
+ case LIST:
+ _list_inputs(m, arg[0], _domain_chain(m, arg[1]), kit.Select(NAME, arg, 3), kit.Select("", arg, 4))
+ }
}
}},
INSERT: {Name: "insert key sub type arg...", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
+ defer m.ProcessRefresh3ms()
switch arg[2] {
case ZONE: // insert key sub type zone arg...
- _list_insert(m, arg[0], _domain_chain(m, kit.Keys(arg[1], kit.KeyHash(arg[3]))), arg[4:]...)
+ _zone_insert(m, arg[0], _domain_chain(m, arg[1]), arg[3], arg[4:]...)
case HASH:
_hash_insert(m, arg[0], _domain_chain(m, arg[1]), arg[3:]...)
case LIST:
_list_insert(m, arg[0], _domain_chain(m, arg[1]), arg[3:]...)
}
- m.ProcessRefresh3ms()
}},
DELETE: {Name: "delete key sub type field value", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
+ defer m.ProcessRefresh3ms()
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])
+ // _list_delete(m, arg[0], _domain_chain(m, kit.Keys(arg[1], kit.KeyHash(arg[3]))), arg[4], arg[5])
case HASH:
_hash_delete(m, arg[0], _domain_chain(m, arg[1]), arg[3], arg[4])
case LIST:
- _list_delete(m, arg[0], _domain_chain(m, arg[1]), arg[3], arg[4])
+ // _list_delete(m, arg[0], _domain_chain(m, arg[1]), arg[3], arg[4])
}
- m.ProcessRefresh3ms()
}},
MODIFY: {Name: "modify key sub type field value arg...", Help: "编辑", Hand: func(m *ice.Message, arg ...string) {
switch arg[2] {
case ZONE: // modify key sub type zone id field value
- _list_modify(m, arg[0], _domain_chain(m, kit.Keys(arg[1], kit.KeyHash(arg[3]))), ID, arg[4], arg[5:]...)
+ _zone_modify(m, arg[0], _domain_chain(m, arg[1]), arg[3], arg[4], arg[5:]...)
case HASH:
_hash_modify(m, arg[0], _domain_chain(m, arg[1]), arg[3], arg[4], arg[5:]...)
case LIST:
@@ -207,14 +221,12 @@ var Index = &ice.Context{Name: MDB, Help: "数据模块", Commands: ice.Commands
PRUNES: {Name: "prunes key sub type [field value]...", Help: "清理", Hand: func(m *ice.Message, arg ...string) {
switch arg[2] {
case ZONE: // prunes key sub type zone field value
- _list_prunes(m, arg[0], _domain_chain(m, kit.Keys(arg[1], kit.KeyHash(arg[3]))), arg[4:]...)
+ // _list_prunes(m, arg[0], _domain_chain(m, kit.Keys(arg[1], kit.KeyHash(arg[3]))), arg[4:]...)
case HASH:
_hash_prunes(m, arg[0], _domain_chain(m, arg[1]), arg[3:]...)
- m.Tables(func(value ice.Maps) {
- _hash_delete(m, arg[0], _domain_chain(m, arg[1]), HASH, value[HASH])
- })
+ m.Tables(func(value ice.Maps) { _hash_delete(m, arg[0], _domain_chain(m, arg[1]), HASH, value[HASH]) })
case LIST:
- _list_prunes(m, arg[0], _domain_chain(m, arg[1]), arg[3:]...)
+ // _list_prunes(m, arg[0], _domain_chain(m, arg[1]), arg[3:]...)
}
}},
EXPORT: {Name: "export key sub type file", Help: "导出", Hand: func(m *ice.Message, arg ...string) {
@@ -223,10 +235,12 @@ var Index = &ice.Context{Name: MDB, Help: "数据模块", Commands: ice.Commands
}
switch file := _file_name(m, arg...); arg[2] {
case ZONE:
+ m.OptionFields(ZoneShort(m), m.Config(FIELD))
_zone_export(m, arg[0], _domain_chain(m, arg[1]), file)
case HASH:
_hash_export(m, arg[0], _domain_chain(m, arg[1]), file)
case LIST:
+ m.OptionFields(m.Config(FIELD))
_list_export(m, arg[0], _domain_chain(m, arg[1]), file)
}
}},
@@ -249,3 +263,35 @@ func init() {
SEARCH, ENGINE, PLUGIN, RENDER,
)
}
+func AutoConfig(args ...ice.Any) *ice.Action {
+ return &ice.Action{Hand: func(m *ice.Message, arg ...string) {
+ if cs := m.Target().Configs; cs[m.CommandKey()] == nil && len(args) > 0 {
+ cs[m.CommandKey()] = &ice.Config{Value: kit.Data(args...)}
+ m.Load(m.CommandKey())
+ }
+
+ inputs := []ice.Any{}
+ kit.Fetch(kit.Split(m.Config(FIELD)), func(i int, k string) {
+ switch k {
+ case TIME, HASH, ID:
+ return
+ }
+ inputs = append(inputs, k)
+ })
+
+ cs := m.Target().Commands
+ if cs[m.CommandKey()] == nil {
+ return
+ }
+
+ if cs[m.CommandKey()].Actions[INSERT] != nil {
+ if cs[m.CommandKey()].Meta[INSERT] == nil {
+ m.Design(INSERT, "添加", append([]ice.Any{ZONE}, inputs...)...)
+ }
+ } else if cs[m.CommandKey()].Actions[CREATE] != nil {
+ if cs[m.CommandKey()].Meta[CREATE] == nil {
+ m.Design(CREATE, "创建", inputs...)
+ }
+ }
+ }}
+}
diff --git a/base/mdb/plugin.go b/base/mdb/plugin.go
index 4edfc307..6186e673 100644
--- a/base/mdb/plugin.go
+++ b/base/mdb/plugin.go
@@ -2,34 +2,10 @@ package mdb
import (
ice "shylinux.com/x/icebergs"
- kit "shylinux.com/x/toolkits"
)
const PLUGIN = "plugin"
func init() {
- Index.Merge(&ice.Context{Configs: ice.Configs{
- PLUGIN: {Name: PLUGIN, Help: "插件", Value: kit.Data(SHORT, TYPE, FIELD, "time,type,name,text")},
- }, Commands: ice.Commands{
- PLUGIN: {Name: "plugin type name text auto", Help: "插件", Actions: ice.Actions{
- CREATE: {Name: "create type name text", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
- m.Option(NAME, kit.Select(m.Option(TYPE), m.Option(NAME)))
- m.Option(TYPE, kit.Ext(m.Option(TYPE)))
- m.Cmdy(INSERT, m.PrefixKey(), "", HASH, m.OptionSimple("type,name,text"))
- }},
- }, Hand: func(m *ice.Message, arg ...string) {
- if len(arg) > 1 {
- m.Cmdy(SELECT, m.PrefixKey(), "", HASH, m.Config(SHORT), arg, func(value ice.Map) {
- m.Cmdy(kit.Keys(value[TEXT], value[NAME]), m.CommandKey(), arg[0], arg[1], kit.Select("", arg, 2), kit.Slice(arg, 3))
- })
- return
- }
- if HashSelect(m, arg...); len(arg) == 0 {
- m.Sort(TYPE)
- } else if len(arg) == 1 {
- m.DisplayStoryJSON()
- m.Echo(kit.Formats(m.Confv(m.Append(NAME), "meta.plug")))
- }
- }},
- }})
+ Index.MergeCommands(ice.Commands{PLUGIN: {Name: "plugin type name text auto", Help: "插件", Actions: RenderAction()}})
}
diff --git a/base/mdb/render.go b/base/mdb/render.go
index 87a2425e..c4c0f102 100644
--- a/base/mdb/render.go
+++ b/base/mdb/render.go
@@ -8,28 +8,31 @@ import (
const RENDER = "render"
func init() {
- Index.Merge(&ice.Context{Configs: ice.Configs{
- RENDER: {Name: RENDER, Help: "渲染", Value: kit.Data(SHORT, TYPE, FIELD, "time,type,name,text")},
- }, Commands: ice.Commands{
- RENDER: {Name: "render type name text auto", Help: "渲染", Actions: ice.Actions{
- CREATE: {Name: "create type name text", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
- m.Option(NAME, kit.Select(m.Option(TYPE), m.Option(NAME)))
- m.Option(TYPE, kit.Ext(m.Option(TYPE)))
- m.Cmdy(INSERT, m.PrefixKey(), "", HASH, m.OptionSimple("type,name,text"))
- }},
- }, Hand: func(m *ice.Message, arg ...string) {
- if len(arg) > 1 {
- m.Cmdy(SELECT, m.PrefixKey(), "", HASH, m.Config(SHORT), arg, func(value ice.Map) {
- m.Cmdy(kit.Keys(value[TEXT], value[NAME]), m.CommandKey(), arg[0], arg[1], kit.Select("", arg, 2), kit.Slice(arg, 3))
- })
- return
- }
- if HashSelect(m, arg...); len(arg) == 0 {
- m.Sort(TYPE)
- } else if len(arg) == 1 {
- m.DisplayStoryJSON()
- m.Echo(kit.Formats(m.Confv(m.Append(NAME), "meta.plug")))
+ Index.MergeCommands(ice.Commands{RENDER: {Name: "render type name text auto", Help: "渲染", Actions: RenderAction()}})
+}
+
+func RenderAction(args ...ice.Any) ice.Actions {
+ return ice.MergeAction(ice.Actions{
+ ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
+ if cs := m.Target().Configs; cs[m.CommandKey()] == nil {
+ cs[m.CommandKey()] = &ice.Config{Value: kit.Data(SHORT, TYPE)}
}
}},
- }})
+ CREATE: {Name: "create type name text", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
+ m.Option(TYPE, kit.Ext(m.Option(TYPE)))
+ m.Option(NAME, kit.Select(m.Option(TYPE), m.Option(NAME)))
+ m.Cmdy(INSERT, m.PrefixKey(), "", HASH, m.OptionSimple("type,name,text"))
+ }},
+ SELECT: {Name: "select type name text auto", Help: "渲染", Hand: func(m *ice.Message, arg ...string) {
+ if len(arg) > 1 {
+ for _, k := range kit.Split(arg[0]) {
+ HashSelect(m.Spawn(ice.OptionFields("")), k).Tables(func(value ice.Maps) {
+ m.Cmdy(kit.Keys(value[TEXT], value[NAME]), m.CommandKey(), k, arg[1], kit.Select("", arg, 2), kit.Slice(arg, 3))
+ })
+ }
+ return
+ }
+ HashSelect(m, arg...)
+ }},
+ })
}
diff --git a/base/mdb/search.go b/base/mdb/search.go
index aba1ef2c..33dc9322 100644
--- a/base/mdb/search.go
+++ b/base/mdb/search.go
@@ -2,32 +2,10 @@ package mdb
import (
ice "shylinux.com/x/icebergs"
- kit "shylinux.com/x/toolkits"
)
const SEARCH = "search"
func init() {
- Index.Merge(&ice.Context{Configs: ice.Configs{
- SEARCH: {Name: SEARCH, Help: "搜索", Value: kit.Data(SHORT, TYPE, FIELD, "time,type,name,text")},
- }, Commands: ice.Commands{
- SEARCH: {Name: "search type name text auto", Help: "搜索", Actions: ice.Actions{
- CREATE: {Name: "create type name text", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
- m.Option(NAME, kit.Select(m.Option(TYPE), m.Option(NAME)))
- m.Option(TYPE, kit.Ext(m.Option(TYPE)))
- m.Cmdy(INSERT, m.PrefixKey(), "", HASH, m.OptionSimple("type,name,text"))
- }},
- }, Hand: func(m *ice.Message, arg ...string) {
- if len(arg) > 1 {
- m.Cmdy(SELECT, m.PrefixKey(), "", HASH, m.Config(SHORT), kit.Slice(arg, 0, 1), func(value ice.Map) {
- m.OptionFields(kit.Select("ctx,cmd,type,name,text", kit.Select(m.OptionFields())))
- m.Cmdy(kit.Keys(value[TEXT], value[NAME]), m.CommandKey(), arg[0], arg[1], kit.Select("", arg, 2), kit.Slice(arg, 3))
- })
- return
- }
- if HashSelect(m, arg...); len(arg) == 0 {
- m.Sort(TYPE)
- }
- }},
- }})
+ Index.MergeCommands(ice.Commands{SEARCH: {Name: "search type name text auto", Help: "搜索", Actions: RenderAction()}})
}
diff --git a/base/mdb/zone.go b/base/mdb/zone.go
index 2039aef8..60a3e26f 100644
--- a/base/mdb/zone.go
+++ b/base/mdb/zone.go
@@ -2,63 +2,62 @@ package mdb
import (
"encoding/csv"
- "os"
"path"
- "sort"
- "strings"
ice "shylinux.com/x/icebergs"
kit "shylinux.com/x/toolkits"
+ "shylinux.com/x/toolkits/logs"
+ "shylinux.com/x/toolkits/miss"
)
func _zone_fields(m *ice.Message) []string {
- return kit.Split(kit.Select("zone,id,time,type,name,text", m.OptionFields()))
+ return kit.Split(kit.Select(ZONE_FIELD, m.OptionFields()))
+}
+func _zone_inputs(m *ice.Message, prefix, chain, zone string, field, value string) {
+ if field == m.Conf(prefix, kit.Keys(chain, kit.Keym(SHORT))) {
+ _hash_inputs(m, prefix, chain, field, value)
+ return
+ }
+ h := _hash_select_fields(m, prefix, chain, zone, HASH)
+ defer m.RLock(prefix, chain)()
+ _list_inputs(m, prefix, _domain_chain(m, kit.Keys(chain, HASH, h)), field, value)
+}
+func _zone_insert(m *ice.Message, prefix, chain, zone string, arg ...string) {
+ h := _hash_select_fields(m, prefix, chain, zone, HASH)
+ if h == "" {
+ h = _hash_insert(m, prefix, chain, m.Conf(prefix, kit.Keys(chain, kit.Keym(SHORT))), zone)
+ }
+ m.Assert(h != "")
+ defer m.Lock(prefix, chain)()
+ _list_insert(m, prefix, _domain_chain(m, kit.Keys(chain, HASH, h)), arg...)
+}
+func _zone_modify(m *ice.Message, prefix, chain, zone, id string, arg ...string) {
+ h := _hash_select_fields(m, prefix, chain, zone, HASH)
+ m.Assert(h != "")
+ defer m.RLock(prefix, chain)()
+ _list_modify(m, prefix, _domain_chain(m, kit.Keys(chain, HASH, h)), ID, id, arg...)
}
func _zone_select(m *ice.Message, prefix, chain, zone string, id string) {
+ if zone == "" {
+ _hash_select(m, prefix, chain, HASH, FOREACH)
+ return
+ }
if zone == RANDOM {
zone = RANDOMS
}
fields := _zone_fields(m)
- cb := m.OptionCB(SELECT)
- m.Richs(prefix, chain, kit.Select(FOREACH, zone), func(key string, val ice.Map) {
- if val = kit.GetMeta(val); zone == "" {
- if m.OptionFields() == DETAIL {
- m.Push(DETAIL, val)
- } else {
- m.Push(key, val, fields)
- }
- return
- }
-
- m.Grows(prefix, kit.Keys(chain, HASH, key), ID, id, func(index int, value ice.Map) {
- switch value = kit.GetMeta(value); cb := cb.(type) {
- case func(string, []string, ice.Map, ice.Map):
- cb(key, fields, value, val)
- case func(string, ice.Map, ice.Map):
- cb(key, value, val)
- case func(string, ice.Map):
- cb(key, value)
- case func(ice.Map):
- cb(value)
- case func(ice.Maps):
- res := ice.Maps{}
- for k, v := range value {
- res[k] = kit.Format(v)
- }
- cb(res)
- default:
- if m.FieldsIsDetail() {
- m.Push(DETAIL, value)
- } else {
- m.Push(key, value, fields, val)
- }
- }
+ defer m.RLock(prefix, chain)()
+ m.Richs(prefix, chain, kit.Select(FOREACH, zone), func(key string, val Map) {
+ chain := kit.Keys(chain, HASH, key)
+ defer m.RLock(prefix, chain)()
+ m.Grows(prefix, chain, ID, id, func(value ice.Map) {
+ _mdb_select(m, key, value, fields, val)
})
})
}
func _zone_export(m *ice.Message, prefix, chain, file string) {
- f, p, e := kit.Create(kit.Keys(file, CSV))
+ f, p, e := miss.CreateFile(kit.Keys(file, CSV))
m.Assert(e)
defer f.Close()
@@ -66,21 +65,24 @@ func _zone_export(m *ice.Message, prefix, chain, file string) {
defer w.Flush()
fields := _zone_fields(m)
- fields = append(fields, EXTRA)
+ if kit.IndexOf(fields, EXTRA) == -1 {
+ fields = append(fields, EXTRA)
+ }
w.Write(fields)
keys := []string{}
- m.Richs(prefix, chain, FOREACH, func(key string, val ice.Map) {
- keys = append(keys, key)
- })
- sort.Strings(keys)
+ m.Richs(prefix, chain, FOREACH, func(key string, val ice.Map) { keys = append(keys, key) })
+ kit.Sort(keys)
count := 0
+ defer m.Lock(prefix, chain)()
for _, key := range keys {
m.Richs(prefix, chain, key, func(key string, val ice.Map) {
val = kit.GetMeta(val)
- m.Grows(prefix, kit.Keys(chain, HASH, key), "", "", func(index int, value ice.Map) {
+ chain := kit.Keys(chain, HASH, key)
+ defer m.RLock(prefix, chain)()
+ m.Grows(prefix, chain, "", "", func(value ice.Map) {
value = kit.GetMeta(value)
list := []string{}
@@ -98,10 +100,8 @@ func _zone_export(m *ice.Message, prefix, chain, file string) {
m.Echo(p)
}
func _zone_import(m *ice.Message, prefix, chain, file string) {
- f, e := os.Open(kit.Keys(file, CSV))
- if m.Warn(e) {
- return
- }
+ f, e := miss.OpenFile(kit.Keys(file, CSV))
+ m.Assert(e)
defer f.Close()
r := csv.NewReader(f)
@@ -111,6 +111,7 @@ func _zone_import(m *ice.Message, prefix, chain, file string) {
list := ice.Maps{}
zkey := kit.Select(head[0], m.OptionFields())
+ defer m.Lock(prefix, chain)()
for {
line, e := r.Read()
if e != nil {
@@ -135,7 +136,11 @@ func _zone_import(m *ice.Message, prefix, chain, file string) {
list[zone] = m.Rich(prefix, chain, kit.Data(zkey, zone))
}
- m.Grow(prefix, kit.Keys(chain, HASH, list[zone]), data)
+ func() {
+ chain := kit.Keys(chain, HASH, list[zone])
+ defer m.Lock(prefix, chain)()
+ m.Grow(prefix, chain, data)
+ }()
count++
}
@@ -143,61 +148,36 @@ func _zone_import(m *ice.Message, prefix, chain, file string) {
m.Echo("%d", count)
}
+const (
+ ZONE_FIELD = "zone,id,time,type,name,text"
+)
const ZONE = "zone"
func ZoneAction(args ...ice.Any) ice.Actions {
- _zone := func(m *ice.Message) string { return kit.Select(ZONE, m.Config(SHORT)) }
-
return ice.Actions{ice.CTX_INIT: AutoConfig(args...),
INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) {
- arg[0] = strings.TrimPrefix(arg[0], "extra.")
- arg[0] = kit.Select(arg[0], m.Config(kit.Keys(ALIAS, arg[0])))
- switch arg[0] {
- case ice.POD:
- m.Cmdy("route")
- case ice.CTX:
- m.Cmdy("context")
- case ice.CMD:
- m.Cmdy("context", kit.Select(m.Option(ice.CTX), m.Option(kit.Keys(EXTRA, ice.CTX))), "command")
- case ice.ARG:
-
- case "index":
- m.OptionFields(arg[0])
- m.Cmdy("command", SEARCH, "command", kit.Select("", arg, 1))
-
- case _zone(m):
- m.Cmdy(INPUTS, m.PrefixKey(), "", HASH, arg)
- default:
- m.Cmdy(INPUTS, m.PrefixKey(), "", ZONE, m.Option(_zone(m)), arg)
- }
+ ZoneInputs(m, arg)
}},
CREATE: {Name: "create zone", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
- m.Cmdy(INSERT, m.PrefixKey(), "", HASH, arg)
+ ZoneCreate(m, arg)
}},
REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
- m.Cmdy(DELETE, m.PrefixKey(), "", HASH, m.OptionSimple(_zone(m)), arg)
+ ZoneRemove(m, arg)
}},
INSERT: {Name: "insert", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
- if len(arg) == 0 {
- arg = m.OptionSimple(_zone(m), m.Config(FIELD))
- }
- m.Cmdy(INSERT, m.PrefixKey(), "", HASH, _zone(m), arg[1])
- m.Cmdy(INSERT, m.PrefixKey(), "", ZONE, m.Option(_zone(m)), arg[2:])
+ ZoneInsert(m, arg)
}},
MODIFY: {Name: "modify", Help: "编辑", Hand: func(m *ice.Message, arg ...string) {
- m.Cmdy(MODIFY, m.PrefixKey(), "", ZONE, m.Option(_zone(m)), m.Option(ID), arg)
+ ZoneModify(m, arg)
}},
- PLUGIN: {Name: "plugin extra.pod extra.ctx extra.cmd extra.arg", Help: "插件", Hand: func(m *ice.Message, arg ...string) {
- m.Cmdy(MODIFY, m.PrefixKey(), "", ZONE, m.Option(_zone(m)), m.Option(ID), arg)
+ SELECT: {Name: "select", Help: "列表", Hand: func(m *ice.Message, arg ...string) {
+ ZoneSelect(m, arg...)
}},
EXPORT: {Name: "export", Help: "导出", Hand: func(m *ice.Message, arg ...string) {
- m.Option(ice.CACHE_LIMIT, "-1")
- m.OptionFields(_zone(m), m.Config(FIELD))
- m.Cmdy(EXPORT, m.PrefixKey(), "", ZONE)
+ ZoneExport(m, arg)
}},
IMPORT: {Name: "import", Help: "导入", Hand: func(m *ice.Message, arg ...string) {
- m.OptionFields(_zone(m))
- m.Cmdy(IMPORT, m.PrefixKey(), "", ZONE)
+ ZoneImport(m, arg)
}},
PREV: {Name: "prev", Help: "上一页", Hand: func(m *ice.Message, arg ...string) {
PrevPage(m, arg[0], arg[1:]...)
@@ -205,28 +185,56 @@ func ZoneAction(args ...ice.Any) ice.Actions {
NEXT: {Name: "next", Help: "下一页", Hand: func(m *ice.Message, arg ...string) {
NextPageLimit(m, arg[0], arg[1:]...)
}},
- SELECT: {Name: "select", Help: "列表", Hand: func(m *ice.Message, arg ...string) {
- ZoneSelect(m, arg...)
- }},
}
}
+func ZoneShort(m *ice.Message) string {
+ return kit.Select(ZONE, m.Config(SHORT), m.Config(SHORT) != UNIQ)
+}
+func ZoneField(m *ice.Message) string { return kit.Select(ZONE_FIELD, m.Config(FIELD)) }
+func ZoneArgs(m *ice.Message, arg ...Any) []string {
+ return _mdb_args(m, ZoneField(m), arg...)
+}
+
+func ZoneInputs(m *ice.Message, arg ...Any) {
+ m.Cmdy(INPUTS, m.PrefixKey(), "", ZONE, ZoneArgs(m, arg...))
+}
+func ZoneCreate(m *ice.Message, arg ...Any) {
+ m.Cmdy(INSERT, m.PrefixKey(), "", HASH, arg)
+}
+func ZoneRemove(m *ice.Message, arg ...Any) {
+ m.Cmdy(DELETE, m.PrefixKey(), "", HASH, m.OptionSimple(ZoneShort(m)), arg)
+}
+func ZoneInsert(m *ice.Message, arg ...Any) {
+ args := kit.Simple(arg...)
+ m.Cmdy(INSERT, m.PrefixKey(), "", ZONE, args[1], ZoneArgs(m, args[2:]))
+}
+func ZoneModify(m *ice.Message, arg ...Any) {
+ m.Cmdy(MODIFY, m.PrefixKey(), "", ZONE, m.Option(ZoneShort(m)), m.Option(ID), ZoneArgs(m, arg...))
+}
func ZoneSelect(m *ice.Message, arg ...string) *ice.Message {
arg = kit.Slice(arg, 0, 2)
m.Fields(len(arg), kit.Fields(TIME, m.Config(SHORT), COUNT), m.Config(FIELD))
- if m.Cmdy(SELECT, m.PrefixKey(), "", ZONE, arg); kit.Select("", arg, 0) == "" {
+ if m.Cmdy(SELECT, m.PrefixKey(), "", ZONE, arg, logs.FileLineMeta(logs.FileLine(-1, 3))); len(arg) == 0 {
if m.Config(SHORT) != "" {
m.Sort(m.Config(SHORT))
}
- m.PushAction(REMOVE)
- }
- if len(arg) == 0 {
+ m.PushAction(m.Config(ACTION), REMOVE)
m.StatusTimeCount()
- }
- if len(arg) == 1 {
- m.StatusTimeCountTotal(m.Conf(m.PrefixKey(), kit.Keys(HASH, kit.Hashs(arg[0]), kit.Keym("count"))))
+ } else if len(arg) == 1 {
+ m.StatusTimeCountTotal(m.Conf("", kit.Keys(HASH, HashSelectFields(m, arg[0], HASH), kit.Keym(COUNT))))
}
return m
}
+func ZoneExport(m *ice.Message, arg ...Any) {
+ m.Cmdy(EXPORT, m.PrefixKey(), "", ZONE, arg)
+}
+func ZoneImport(m *ice.Message, arg ...Any) {
+ m.Cmdy(IMPORT, m.PrefixKey(), "", ZONE, arg)
+}
+func ZoneSelectPage(m *ice.Message, arg ...string) *ice.Message {
+ m.OptionPages(kit.Slice(arg, 2)...)
+ return ZoneSelect(m, arg...)
+}
func ZoneSelectAll(m *ice.Message, arg ...string) *ice.Message {
m.Option(ice.CACHE_LIMIT, "-1")
return ZoneSelect(m, arg...)
diff --git a/base/nfs/cat.go b/base/nfs/cat.go
index bf58c891..8bd460b6 100644
--- a/base/nfs/cat.go
+++ b/base/nfs/cat.go
@@ -4,78 +4,41 @@ import (
"bufio"
"bytes"
"io"
- "os"
"path"
"strings"
ice "shylinux.com/x/icebergs"
- "shylinux.com/x/icebergs/base/aaa"
- "shylinux.com/x/icebergs/base/mdb"
kit "shylinux.com/x/toolkits"
)
-type ReadCloser struct {
- r io.Reader
-}
-
-func (r *ReadCloser) Read(buf []byte) (int, error) {
- return r.r.Read(buf)
-}
-func (r *ReadCloser) Close() error {
- if c, ok := r.r.(io.Closer); ok {
- return c.Close()
- }
- return nil
-}
-func NewReadCloser(r io.Reader) *ReadCloser {
- return &ReadCloser{r: r}
-}
-
-var rewriteList = []ice.Any{}
-
-func AddRewrite(cb ice.Any) { rewriteList = append(rewriteList, cb) }
-
-func _cat_right(m *ice.Message, name string) bool {
- return aaa.RoleRight(m, m.Option(ice.MSG_USERROLE), strings.Split(name, ice.PS)...)
-}
-func _cat_find(m *ice.Message, name string) io.ReadCloser {
+func _cat_find(m *ice.Message, name string) (io.ReadCloser, error) {
if m.Option(CAT_CONTENT) != "" {
- return NewReadCloser(bytes.NewBufferString(m.Option(CAT_CONTENT)))
+ return NewReadCloser(bytes.NewBufferString(m.Option(CAT_CONTENT))), nil
}
-
- // 模块回调
- for _, h := range rewriteList {
- switch h := h.(type) {
- case func(m *ice.Message, name string) io.ReadCloser:
- if r := h(m, name); r != nil {
- return r
- }
- case func(m *ice.Message, name string) []byte:
- if b := h(m, name); b != nil {
- return NewReadCloser(bytes.NewBuffer(b))
- }
- case func(m *ice.Message, name string) string:
- if s := h(m, name); s != "" {
- return NewReadCloser(bytes.NewBufferString(s))
- }
- default:
- m.Error(true, ice.ErrNotImplement)
+ return OpenFile(m, path.Join(m.Option(DIR_ROOT), name))
+}
+func _cat_size(m *ice.Message, p string) (nline int) {
+ if f, e := OpenFile(m, p); m.Warn(e) {
+ defer f.Close()
+ for bio := bufio.NewScanner(f); bio.Scan(); nline++ {
+ bio.Text()
}
}
-
- // 本地文件
- if f, e := os.Open(path.Join(m.Option(DIR_ROOT), name)); e == nil {
- return f
+ return nline
+}
+func _cat_hash(m *ice.Message, p string) string {
+ if f, e := OpenFile(m, p); !m.Warn(e) {
+ defer f.Close()
+ return kit.Hashs(f)
}
- return nil
+ return ""
}
func _cat_list(m *ice.Message, name string) {
- if m.Warn(!_cat_right(m, name), ice.ErrNotRight) {
+ if !m.Right(m, name) {
return // 没有权限
}
-
- f := _cat_find(m, name)
- if m.Warn(f == nil, ice.ErrNotFound, name) {
+ f, e := _cat_find(m, name)
+ if m.Warn(e, ice.ErrNotFound, name) {
return // 没有文件
}
defer f.Close()
@@ -97,15 +60,15 @@ func _cat_list(m *ice.Message, name string) {
for bio := bufio.NewScanner(f); bio.Scan(); {
cb(bio.Text())
}
+
case func([]string, string):
for bio := bufio.NewScanner(f); bio.Scan(); {
cb(kit.Split(bio.Text()), bio.Text())
}
-
- default:
- buf := make([]byte, ice.MOD_BUFS)
- for begin := 0; true; {
- if n, e := f.Read(buf[begin:]); !m.Warn(e, ice.ErrNotFound, name) {
+ case nil:
+ buf, begin := make([]byte, ice.MOD_BUFS), 0
+ for {
+ if n, e := f.Read(buf[begin:]); !m.Warn(e, ice.ErrNotValid, name) {
m.Log_IMPORT(FILE, name, SIZE, n)
if begin += n; begin < len(buf) {
buf = buf[:begin]
@@ -117,6 +80,8 @@ func _cat_list(m *ice.Message, name string) {
}
}
m.Echo(string(buf))
+ default:
+ m.ErrorNotImplement(cb)
}
}
@@ -125,6 +90,7 @@ const (
TEMPLATE = "template"
WEBSITE = "website"
+ STDIO = "stdio"
SOURCE = "source"
SCRIPT = "script"
BINARY = "binary"
@@ -155,15 +121,15 @@ const (
YML = "yml"
ZML = "zml"
+ PNG = "png"
+ JPG = "jpg"
+ MP4 = "mp4"
+
PWD = "./"
+ PS = ice.PS
+ PT = ice.PT
)
-const (
- PATH = "path"
- FILE = "file"
- LINE = "line"
- SIZE = "size"
-)
const CAT = "cat"
func init() {
@@ -177,20 +143,13 @@ func init() {
),
)},
}, Commands: ice.Commands{
- CAT: {Name: "cat path auto", Help: "文件", Actions: ice.Actions{
- ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
- m.Cmd(mdb.RENDER, mdb.CREATE, m.CommandKey(), m.PrefixKey())
- }},
- mdb.RENDER: {Name: "render type name text", Help: "渲染", Hand: func(m *ice.Message, arg ...string) {
- _cat_list(m, path.Join(arg[2], arg[1]))
- }},
- }, Hand: func(m *ice.Message, arg ...string) {
+ CAT: {Name: "cat path auto", Help: "文件", Hand: func(m *ice.Message, arg ...string) {
if len(arg) == 0 || strings.HasSuffix(arg[0], ice.PS) {
m.Cmdy(DIR, arg)
return
}
if m.Option(DIR_ROOT) != "" {
- m.Info("dir_root: %v", m.Option(DIR_ROOT))
+ m.Log_SELECT(DIR_ROOT, m.Option(DIR_ROOT))
}
_cat_list(m, arg[0])
}},
diff --git a/base/nfs/dir.go b/base/nfs/dir.go
index c0c8fd10..251fee41 100644
--- a/base/nfs/dir.go
+++ b/base/nfs/dir.go
@@ -1,9 +1,6 @@
package nfs
import (
- "bufio"
- "crypto/sha1"
- "io/ioutil"
"os"
"path"
"regexp"
@@ -15,57 +12,38 @@ import (
kit "shylinux.com/x/toolkits"
)
+func _dir_size(m *ice.Message, p string) int {
+ if ls, e := ReadDir(m, p); !m.Warn(e) {
+ return len(ls)
+ }
+ return 0
+}
+func _dir_hash(m *ice.Message, p string) string {
+ if ls, e := ReadDir(m, p); !m.Warn(e) {
+ meta := []string{}
+ for _, s := range ls {
+ meta = append(meta, kit.Format("%s%d%s", s.Name(), s.Size(), s.ModTime()))
+ }
+ return kit.Hashs(meta)
+ }
+ return ""
+}
func _dir_list(m *ice.Message, root string, name string, level int, deep bool, dir_type string, dir_reg *regexp.Regexp, fields []string) *ice.Message {
- if !_cat_right(m, path.Join(root, name)) {
+ if !m.Right(m, path.Join(root, name)) {
return m // 没有权限
}
- if len(ice.Info.Pack) > 0 && m.Option(DIR_PACK) == ice.TRUE {
- for k, b := range ice.Info.Pack {
- p := strings.TrimPrefix(k, root)
- if !strings.HasPrefix(p, name) {
- if p = strings.TrimPrefix(k, root+ice.PS); !strings.HasPrefix(p, name) {
- if p = strings.TrimPrefix(k, ice.PS); !strings.HasPrefix(p, name) {
- continue
- }
- }
- }
-
- m.Debug("dir binpack %s", p)
- for _, field := range fields {
- switch field {
- case PATH:
- m.Push(field, p)
- case SIZE:
- m.Push(field, len(b))
- default:
- m.Push(field, "")
- }
- }
- }
- return m // 打包文件
- }
-
- list, e := ioutil.ReadDir(path.Join(root, name))
+ list, e := ReadDir(m, path.Join(root, name))
if e != nil { // 单个文件
- ls, _ := ioutil.ReadDir(path.Dir(path.Join(root, name)))
- for _, k := range ls {
- if k.Name() == path.Base(name) {
- list = append(list, k)
+ ls, _ := ReadDir(m, path.Dir(path.Join(root, name)))
+ for _, s := range ls {
+ if s.Name() == path.Base(name) {
+ list = append(list, s)
}
}
name = path.Dir(name)
}
- // 文件排序
- for i := 0; i < len(list)-1; i++ {
- for j := i + 1; j < len(list); j++ {
- if list[i].Name() > list[j].Name() {
- list[i], list[j] = list[j], list[i]
- }
- }
- }
-
for _, f := range list {
if f.Name() == ice.PT || f.Name() == ".." {
continue
@@ -74,7 +52,7 @@ func _dir_list(m *ice.Message, root string, name string, level int, deep bool, d
continue
}
- p := path.Join(root, name, f.Name())
+ p, pp := path.Join(root, name, f.Name()), path.Join(name, f.Name())
isDir := f.IsDir() || kit.IsDir(p)
if !(dir_type == TYPE_CAT && isDir || dir_type == TYPE_DIR && !isDir) && (dir_reg == nil || dir_reg.MatchString(f.Name())) {
switch cb := m.OptionCB(DIR).(type) {
@@ -86,7 +64,7 @@ func _dir_list(m *ice.Message, root string, name string, level int, deep bool, d
continue
case nil:
default:
- m.Error(true, "what: %v: %v", ice.ErrNotImplement, cb)
+ m.ErrorNotImplement(cb)
}
for _, field := range fields {
@@ -96,78 +74,54 @@ func _dir_list(m *ice.Message, root string, name string, level int, deep bool, d
case mdb.TYPE:
m.Push(field, kit.Select(CAT, DIR, isDir))
- case "tree":
+ case TREE:
if level == 0 {
m.Push(field, f.Name())
} else {
m.Push(field, strings.Repeat("| ", level-1)+"|-"+f.Name())
}
- case "full":
- m.Push(field, path.Join(root, name, f.Name())+kit.Select("", ice.PS, isDir))
+ case FULL:
+ m.Push(field, p+kit.Select("", ice.PS, isDir))
case PATH:
- m.Push(field, path.Join(name, f.Name())+kit.Select("", ice.PS, isDir))
+ m.Push(field, pp+kit.Select("", ice.PS, isDir))
case FILE:
m.Push(field, f.Name()+kit.Select("", ice.PS, isDir))
- case mdb.NAME:
+ case NAME:
m.Push(field, f.Name())
case SIZE:
if isDir {
- if ls, e := ioutil.ReadDir(path.Join(root, name, f.Name())); e == nil {
- m.Push(field, len(ls))
- } else {
- m.Push(field, 0)
- }
+ m.Push(field, _dir_size(m, p))
} else {
m.Push(field, kit.FmtSize(f.Size()))
}
case LINE:
if isDir {
- if ls, e := ioutil.ReadDir(path.Join(root, name, f.Name())); e == nil {
- m.Push(field, len(ls))
- } else {
- m.Push(field, 0)
- }
+ m.Push(field, _dir_size(m, p))
} else {
- nline := 0
- if f, e := os.Open(p); m.Assert(e) {
- defer f.Close()
- for bio := bufio.NewScanner(f); bio.Scan(); nline++ {
- bio.Text()
- }
- }
- m.Push(field, nline)
+ m.Push(field, _cat_size(m, p))
}
case mdb.HASH, "hashs":
- var h [20]byte
+ h := ""
if isDir {
- if d, e := ioutil.ReadDir(p); m.Assert(e) {
- meta := []string{}
- for _, v := range d {
- meta = append(meta, kit.Format("%s%d%s", v.Name(), v.Size(), v.ModTime()))
- }
- kit.Sort(meta)
- h = sha1.Sum([]byte(strings.Join(meta, "")))
- }
+ h = _dir_hash(m, p)
} else {
- if f, e := ioutil.ReadFile(path.Join(name, f.Name())); m.Assert(e) {
- h = sha1.Sum(f)
- }
+ h = _cat_hash(m, p)
}
-
- m.Push(mdb.HASH, kit.Select(kit.Format(h[:6]), kit.Format(h[:]), field == mdb.HASH))
+ m.Debug("what %v %v", h, p)
+ m.Push(mdb.HASH, kit.Select(h[:6], h[:], field == mdb.HASH))
case mdb.LINK:
- m.PushDownload(mdb.LINK, kit.Select("", f.Name(), !isDir), path.Join(root, name, f.Name()))
+ m.PushDownload(mdb.LINK, kit.Select("", f.Name(), !isDir), p)
case mdb.SHOW:
- switch p := m.MergeURL2("/share/local/"+path.Join(name, f.Name()), ice.POD, m.Option(ice.MSG_USERPOD)); kit.Ext(f.Name()) {
- case "png", "jpg":
+ switch p := m.MergeURL2("/share/local/"+p, ice.POD, m.Option(ice.MSG_USERPOD)); kit.Ext(f.Name()) {
+ case PNG, JPG:
m.PushImages(field, p)
- case "mp4":
+ case MP4:
m.PushVideos(field, p)
default:
m.Push(field, "")
}
- case "action":
+ case mdb.ACTION:
if m.IsCliUA() || m.Option(ice.MSG_USERROLE) == aaa.VOID {
break
}
@@ -178,27 +132,65 @@ func _dir_list(m *ice.Message, root string, name string, level int, deep bool, d
}
}
- switch f.Name() {
- case "node_modules", "pluged", "target", "trash":
- continue
- }
-
if deep && isDir {
- _dir_list(m, root, path.Join(name, f.Name()), level+1, deep, dir_type, dir_reg, fields)
+ switch f.Name() {
+ case "node_modules", "pluged", "target", "trash":
+ continue // 禁用递归
+ }
+
+ _dir_list(m, root, pp, level+1, deep, dir_type, dir_reg, fields)
}
}
return m
}
-func _dir_search(m *ice.Message, kind, name string) {
- msg := _dir_list(m.Spawn(), PWD, "", 0, true, TYPE_BOTH, nil, kit.Split("time,type,name"))
- msg.Tables(func(value ice.Maps) {
- if !strings.Contains(value[mdb.NAME], name) {
- return
- }
- if value[mdb.TYPE] == CAT {
- value[mdb.TYPE] = kit.Ext(value[mdb.NAME])
- }
- m.PushSearch(value)
+
+const (
+ TYPE_ALL = "all"
+ TYPE_CAT = "cat"
+ TYPE_DIR = "dir"
+ TYPE_BOTH = "both"
+)
+const (
+ DIR_ROOT = "dir_root"
+ DIR_TYPE = "dir_type"
+ DIR_DEEP = "dir_deep"
+ DIR_REG = "dir_reg"
+
+ DIR_DEF_FIELDS = "time,path,size,action"
+ DIR_WEB_FIELDS = "time,size,path,action,link"
+ DIR_CLI_FIELDS = "path,size,time"
+)
+const (
+ ROOT = "root"
+ TREE = "tree"
+ FULL = "full"
+ PATH = "path"
+ FILE = "file"
+ NAME = "name"
+ SIZE = "size"
+ LINE = "line"
+)
+const DIR = "dir"
+
+func init() {
+ Index.MergeCommands(ice.Commands{
+ DIR: {Name: "dir path field auto upload", Help: "目录", Actions: ice.Actions{
+ mdb.UPLOAD: {Name: "upload", Help: "上传", Hand: func(m *ice.Message, arg ...string) {
+ m.Upload(m.Option(PATH))
+ }},
+ TRASH: {Name: "trash", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
+ m.Cmdy(TRASH, m.Option(PATH))
+ }},
+ }, Hand: func(m *ice.Message, arg ...string) {
+ if m.Option(DIR_ROOT) != "" {
+ m.Log_SELECT(DIR_ROOT, m.Option(DIR_ROOT))
+ }
+ _dir_list(m, kit.Select(PWD, m.Option(DIR_ROOT)), kit.Select(PWD, arg, 0),
+ 0, m.Option(DIR_DEEP) == ice.TRUE, kit.Select(TYPE_BOTH, m.Option(DIR_TYPE)), kit.Regexp(m.Option(DIR_REG)),
+ kit.Split(kit.Select(kit.Select(DIR_DEF_FIELDS, m.OptionFields()), kit.Join(kit.Slice(arg, 1)))))
+ m.SortTimeR(mdb.TIME)
+ m.StatusTimeCount()
+ }},
})
}
@@ -210,66 +202,3 @@ func Dir(m *ice.Message, sort string) *ice.Message {
m.Copy(m.Cmd(DIR, PWD).Sort(sort))
return m
}
-func MkdirAll(m *ice.Message, p string) error {
- m.Log_EXPORT("mkdir", "dir", p)
- return os.MkdirAll(p, ice.MOD_DIR)
-}
-
-const (
- TYPE_ALL = "all"
- TYPE_CAT = "cat"
- TYPE_DIR = "dir"
- TYPE_BOTH = "both"
-)
-const (
- DIR_PACK = "dir_pack"
- DIR_ROOT = "dir_root"
- DIR_TYPE = "dir_type"
- DIR_DEEP = "dir_deep"
- DIR_REG = "dir_reg"
-
- DIR_DEF_FIELDS = "time,path,size,action"
- DIR_WEB_FIELDS = "time,size,path,action,link"
- DIR_CLI_FIELDS = "path,size,time"
-)
-const DIR = "dir"
-
-func init() {
- Index.Merge(&ice.Context{Configs: ice.Configs{
- DIR: {Name: DIR, Help: "目录", Value: kit.Data()},
- }, Commands: ice.Commands{
- DIR: {Name: "dir path field... auto upload", Help: "目录", Actions: ice.Actions{
- ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
- m.Cmd(mdb.RENDER, mdb.CREATE, m.CommandKey(), m.PrefixKey())
- }},
- mdb.SEARCH: {Name: "search type name", Help: "搜索", Hand: func(m *ice.Message, arg ...string) {
- if arg[0] == mdb.FOREACH {
- return
- }
- _dir_search(m, arg[0], arg[1])
- }},
- mdb.RENDER: {Name: "render type name text", Help: "渲染", Hand: func(m *ice.Message, arg ...string) {
- _dir_list(m, arg[2], arg[1], 0, m.Option(DIR_DEEP) == ice.TRUE, kit.Select(TYPE_BOTH, m.Option(DIR_TYPE)),
- nil, kit.Split(kit.Select("time,size,type,path", m.OptionFields())))
- }},
- mdb.UPLOAD: {Name: "upload", Help: "上传", Hand: func(m *ice.Message, arg ...string) {
- m.Upload(m.Option(PATH))
- }},
- mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
- os.Remove(m.Option(PATH))
- }},
- TRASH: {Name: "trash", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
- m.Cmdy(TRASH, m.Option(PATH))
- }},
- }, Hand: func(m *ice.Message, arg ...string) {
- if m.Option(DIR_ROOT) != "" {
- m.Info("dir_root: %v", m.Option(DIR_ROOT))
- }
- _dir_list(m, kit.Select(PWD, m.Option(DIR_ROOT)), kit.Select(PWD, arg, 0),
- 0, m.Option(DIR_DEEP) == ice.TRUE, kit.Select(TYPE_BOTH, m.Option(DIR_TYPE)), kit.Regexp(m.Option(DIR_REG)),
- kit.Split(kit.Select(kit.Select(DIR_DEF_FIELDS, m.OptionFields()), kit.Join(kit.Slice(arg, 1)))))
- m.SortTimeR(mdb.TIME)
- m.StatusTimeCount()
- }},
- }})
-}
diff --git a/base/nfs/find.go b/base/nfs/find.go
index b3ce0bab..b31beda4 100644
--- a/base/nfs/find.go
+++ b/base/nfs/find.go
@@ -9,11 +9,11 @@ import (
const FIND = "find"
func init() {
- Index.Merge(&ice.Context{Commands: ice.Commands{
+ Index.MergeCommands(ice.Commands{
FIND: {Name: "find path word auto", Help: "搜索", Hand: func(m *ice.Message, arg ...string) {
for _, file := range strings.Split(m.Cmdx("cli.system", FIND, PWD, "-name", arg[1]), ice.NL) {
m.Push(FILE, strings.TrimPrefix(file, PWD))
}
}},
- }})
+ })
}
diff --git a/base/nfs/grep.go b/base/nfs/grep.go
index 9b5d647e..b872f8fd 100644
--- a/base/nfs/grep.go
+++ b/base/nfs/grep.go
@@ -5,10 +5,10 @@ import ice "shylinux.com/x/icebergs"
const GREP = "grep"
func init() {
- Index.Merge(&ice.Context{Commands: ice.Commands{
+ Index.MergeCommands(ice.Commands{
GREP: {Name: "grep path word auto", Help: "搜索", Hand: func(m *ice.Message, arg ...string) {
m.Option("cmd_dir", arg[0])
m.Split(m.Cmdx("cli.system", GREP, "--exclude=.[a-z]*", "--exclude-dir=.[a-z]*", "-rni", arg[1]), "file:line:text", ":")
}},
- }})
+ })
}
diff --git a/base/nfs/nfs.go b/base/nfs/nfs.go
index 0500d67b..173c51a8 100644
--- a/base/nfs/nfs.go
+++ b/base/nfs/nfs.go
@@ -1,9 +1,107 @@
package nfs
-import ice "shylinux.com/x/icebergs"
+import (
+ "io"
+ "io/ioutil"
+ "os"
+
+ ice "shylinux.com/x/icebergs"
+ "shylinux.com/x/toolkits/file"
+)
var Index = &ice.Context{Name: "nfs", Help: "存储模块"}
func init() {
ice.Index.Register(Index, nil, TAR, CAT, DIR, DEFS, SAVE, PUSH, COPY, LINK, TAIL, TRASH, GREP)
}
+
+var DiskFile = file.NewDiskFile()
+var PackFile = file.NewPackFile()
+
+func init() { file.Init(ice.Pulse.OptionFiles(DiskFile, PackFile)) }
+
+func StatFile(m *ice.Message, p string) (os.FileInfo, error) {
+ file := m.OptionFiles()
+ return file.StatFile(p)
+}
+func OpenFile(m *ice.Message, p string) (io.ReadCloser, error) {
+ file := m.OptionFiles()
+ return file.OpenFile(p)
+}
+func CreateFile(m *ice.Message, p string) (io.WriteCloser, string, error) {
+ file := m.OptionFiles()
+ return file.CreateFile(p)
+}
+func AppendFile(m *ice.Message, p string) (io.ReadWriteCloser, string, error) {
+ file := m.OptionFiles()
+ w, e := file.AppendFile(p)
+ return w, p, e
+}
+func WriteFile(m *ice.Message, p string, b []byte) error {
+ file := m.OptionFiles()
+ return file.WriteFile(p, b)
+}
+
+func ReadDir(m *ice.Message, p string) ([]os.FileInfo, error) {
+ file := m.OptionFiles()
+ list, e := file.ReadDir(p)
+ for i := 0; i < len(list)-1; i++ {
+ for j := i + 1; j < len(list); j++ {
+ if list[i].Name() > list[j].Name() {
+ list[i], list[j] = list[j], list[i]
+ }
+ }
+ }
+ return list, e
+}
+func MkdirAll(m *ice.Message, p string) error {
+ file := m.OptionFiles()
+ return file.MkdirAll(p, ice.MOD_DIR)
+}
+func RemoveAll(m *ice.Message, p string) error {
+ file := m.OptionFiles()
+ return file.RemoveAll(p)
+}
+func Remove(m *ice.Message, p string) error {
+ file := m.OptionFiles()
+ return file.Remove(p)
+}
+func Rename(m *ice.Message, oldname string, newname string) error {
+ file := m.OptionFiles()
+ return file.Rename(oldname, newname)
+}
+func Symlink(m *ice.Message, oldname string, newname string) error {
+ file := m.OptionFiles()
+ return file.Symlink(oldname, newname)
+}
+func Link(m *ice.Message, oldname string, newname string) error {
+ file := m.OptionFiles()
+ return file.Link(oldname, newname)
+}
+func Close(m *ice.Message) {
+ file := m.OptionFiles()
+ file.Close()
+}
+
+func ExistsFile(m *ice.Message, p string) bool {
+ file := m.OptionFiles()
+ if _, e := file.StatFile(p); e == nil {
+ return true
+ }
+ return false
+}
+func ReadFile(m *ice.Message, p string) ([]byte, error) {
+ file := m.OptionFiles()
+ if f, e := file.OpenFile(p); e == nil {
+ return ioutil.ReadAll(f)
+ } else {
+ return nil, e
+ }
+}
+
+func NewWriteCloser(w func([]byte) (int, error), c func() error) io.WriteCloser {
+ return file.NewWriteCloser(w, c)
+}
+func NewReadCloser(r io.Reader) io.ReadCloser {
+ return file.NewReadCloser(r)
+}
diff --git a/base/nfs/pack.go b/base/nfs/pack.go
new file mode 100644
index 00000000..36262808
--- /dev/null
+++ b/base/nfs/pack.go
@@ -0,0 +1,63 @@
+package nfs
+
+import (
+ "io"
+ "io/ioutil"
+ "path"
+ "strings"
+
+ ice "shylinux.com/x/icebergs"
+ "shylinux.com/x/icebergs/base/mdb"
+ kit "shylinux.com/x/toolkits"
+)
+
+const PACK = "pack"
+
+func init() {
+ pack := PackFile
+ Index.MergeCommands(ice.Commands{
+ PACK: {Name: "pack path auto upload create", Help: "文件系统", Actions: ice.Actions{
+ mdb.UPLOAD: {Name: "upload", Help: "上传", Hand: func(m *ice.Message, arg ...string) {
+ if b, h, e := m.R.FormFile(mdb.UPLOAD); m.Assert(e) {
+ defer b.Close()
+ if f, p, e := pack.CreateFile(path.Join(m.Option(PATH), h.Filename)); m.Assert(e) {
+ defer f.Close()
+ if n, e := io.Copy(f, b); e == nil {
+ m.Log_IMPORT(FILE, p, SIZE, n)
+ }
+ }
+ }
+ }},
+ mdb.CREATE: {Name: "create path=h1/h2/hi.txt text=hello", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
+ if f, _, e := pack.CreateFile(m.Option(PATH)); e == nil {
+ defer f.Close()
+ f.Write([]byte(m.Option(mdb.TEXT)))
+ }
+ }},
+ mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
+ pack.Remove(path.Clean(m.Option(PATH)))
+ }},
+ }, Hand: func(m *ice.Message, arg ...string) {
+ p := kit.Select("", arg, 0)
+ if p != "" && !strings.HasSuffix(p, PS) {
+ if f, e := pack.OpenFile(p); e == nil {
+ defer f.Close()
+ if b, e := ioutil.ReadAll(f); e == nil {
+ m.Echo(string(b))
+ }
+ }
+ return
+ }
+
+ ls, _ := pack.ReadDir(p)
+ for _, f := range ls {
+ m.Push(mdb.TIME, f.ModTime().Format(ice.MOD_TIME))
+ m.Push(PATH, path.Join(p, f.Name())+kit.Select("", PS, f.IsDir()))
+ m.Push(SIZE, f.Size())
+ }
+ m.Sort("time,path")
+ m.PushAction(mdb.REMOVE)
+ m.StatusTimeCount()
+ }},
+ })
+}
diff --git a/base/nfs/save.go b/base/nfs/save.go
index c97a1a88..cd52f049 100644
--- a/base/nfs/save.go
+++ b/base/nfs/save.go
@@ -1,17 +1,16 @@
package nfs
import (
+ "fmt"
"io"
- "os"
"path"
- "strings"
ice "shylinux.com/x/icebergs"
kit "shylinux.com/x/toolkits"
)
func _defs_file(m *ice.Message, name string, text ...string) {
- if kit.FileExists(path.Join(m.Option(DIR_ROOT), name)) {
+ if ExistsFile(m, path.Join(m.Option(DIR_ROOT), name)) {
return
}
for i, v := range text {
@@ -21,11 +20,11 @@ func _defs_file(m *ice.Message, name string, text ...string) {
_save_file(m, name, text...)
}
func _save_file(m *ice.Message, name string, text ...string) {
- if f, p, e := kit.Create(path.Join(m.Option(DIR_ROOT), name)); m.Assert(e) {
+ if f, p, e := CreateFile(m, path.Join(m.Option(DIR_ROOT), name)); m.Assert(e) {
defer f.Close()
for _, v := range text {
- if n, e := f.WriteString(v); m.Assert(e) {
+ if n, e := fmt.Fprint(f, v); m.Assert(e) {
m.Log_EXPORT(FILE, p, SIZE, n)
}
}
@@ -33,16 +32,11 @@ func _save_file(m *ice.Message, name string, text ...string) {
}
}
func _push_file(m *ice.Message, name string, text ...string) {
- p := path.Join(m.Option(DIR_ROOT), name)
- if strings.Contains(p, ice.PS) {
- MkdirAll(m, path.Dir(p))
- }
-
- if f, e := os.OpenFile(p, os.O_WRONLY|os.O_APPEND|os.O_CREATE, ice.MOD_FILE); m.Assert(e) {
+ if f, p, e := AppendFile(m, path.Join(m.Option(DIR_ROOT), name)); m.Assert(e) {
defer f.Close()
for _, k := range text {
- if n, e := f.WriteString(k); m.Assert(e) {
+ if n, e := fmt.Fprint(f, k); m.Assert(e) {
m.Log_EXPORT(FILE, p, SIZE, n)
}
}
@@ -50,11 +44,11 @@ func _push_file(m *ice.Message, name string, text ...string) {
}
}
func _copy_file(m *ice.Message, name string, from ...string) {
- if f, p, e := kit.Create(path.Join(m.Option(DIR_ROOT), name)); m.Assert(e) {
+ if f, p, e := CreateFile(m, path.Join(m.Option(DIR_ROOT), name)); m.Assert(e) {
defer f.Close()
for _, v := range from {
- if s, e := os.Open(v); !m.Warn(e, ice.ErrNotFound, name) {
+ if s, e := OpenFile(m, path.Join(m.Option(DIR_ROOT), v)); !m.Warn(e, ice.ErrNotFound, name) {
defer s.Close()
if n, e := io.Copy(f, s); !m.Warn(e, ice.ErrNotFound, name) {
@@ -67,23 +61,28 @@ func _copy_file(m *ice.Message, name string, from ...string) {
}
}
func _link_file(m *ice.Message, name string, from string) {
- if from == "" || m.Warn(!kit.FileExists(from), ice.ErrNotFound, from) {
+ if m.Warn(from == "", ice.ErrNotValid, from) {
return
}
- os.Remove(name)
+ name = path.Join(m.Option(DIR_ROOT), name)
+ from = path.Join(m.Option(DIR_ROOT), from)
+ if m.Warn(!ExistsFile(m, from), ice.ErrNotFound, from) {
+ return
+ }
+ Remove(m, name)
MkdirAll(m, path.Dir(name))
- if e := os.Link(from, name); e != nil {
- if m.Warn(os.Symlink(from, name), ice.ErrWarn, from) {
+ if m.Warn(Link(m, from, name)) {
+ if m.Warn(Symlink(m, from, name), ice.ErrWarn, from) {
return
}
}
- m.Log_EXPORT(name, "from", from)
+ m.Log_EXPORT(FILE, name, FROM, from)
m.Echo(name)
-
}
const (
CONTENT = "content"
+ FROM = "from"
)
const DEFS = "defs"
const SAVE = "save"
@@ -92,7 +91,7 @@ const COPY = "copy"
const LINK = "link"
func init() {
- Index.Merge(&ice.Context{Commands: ice.Commands{
+ Index.MergeCommands(ice.Commands{
DEFS: {Name: "defs file text...", Help: "默认", Hand: func(m *ice.Message, arg ...string) {
_defs_file(m, arg[0], arg[1:]...)
}},
@@ -119,5 +118,5 @@ func init() {
LINK: {Name: "link file from", Help: "链接", Hand: func(m *ice.Message, arg ...string) {
_link_file(m, arg[0], arg[1])
}},
- }})
+ })
}
diff --git a/base/nfs/tail.go b/base/nfs/tail.go
index 53dd1b29..5252663b 100644
--- a/base/nfs/tail.go
+++ b/base/nfs/tail.go
@@ -36,11 +36,7 @@ func _tail_count(m *ice.Message, name string) string {
const TAIL = "tail"
func init() {
- Index.Merge(&ice.Context{Configs: ice.Configs{
- TAIL: {Name: TAIL, Help: "日志流", Value: kit.Data(
- mdb.SHORT, mdb.NAME, mdb.FIELD, "time,id,file,text",
- )},
- }, Commands: ice.Commands{
+ Index.MergeCommands(ice.Commands{
TAIL: {Name: "tail name id auto page filter:text create", Help: "日志流", Actions: ice.MergeAction(ice.Actions{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
m.Richs(TAIL, "", mdb.FOREACH, func(key string, value ice.Map) {
@@ -62,7 +58,7 @@ func init() {
mdb.CREATE: {Name: "create file name", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
_tail_create(m, arg...)
}},
- }, mdb.ZoneAction()), Hand: func(m *ice.Message, arg ...string) {
+ }, mdb.ZoneAction(mdb.SHORT, mdb.NAME, mdb.FIELD, "time,id,file,text")), Hand: func(m *ice.Message, arg ...string) {
m.Fields(len(kit.Slice(arg, 0, 2)), "time,name,count,file", m.Config(mdb.FIELD))
m.OptionPage(kit.Slice(arg, 2)...)
@@ -76,5 +72,5 @@ func init() {
m.StatusTimeCountTotal(_tail_count(m, arg[0]))
}
}},
- }})
+ })
}
diff --git a/base/nfs/tar.go b/base/nfs/tar.go
index ffd7f164..bfd5c773 100644
--- a/base/nfs/tar.go
+++ b/base/nfs/tar.go
@@ -15,7 +15,7 @@ import (
const TAR = "tar"
func init() {
- Index.Merge(&ice.Context{Commands: ice.Commands{
+ Index.MergeCommands(ice.Commands{
TAR: {Name: "tar file path auto", Help: "打包", Actions: ice.Actions{
mdb.IMPORT: {Name: "import", Help: "导入", Hand: func(m *ice.Message, arg ...string) {
if len(arg) == 1 {
@@ -63,18 +63,18 @@ func init() {
}
header.Name = strings.TrimPrefix(p, dir_root+ice.PS)
- if err = t.WriteHeader(header); m.Warn(err != nil, "err: %v", err) {
+ if err = t.WriteHeader(header); m.Warn(err) {
return
}
file, err := os.Open(p)
- if m.Warn(err != nil, "err: %v", err) {
+ if m.Warn(err) {
return
}
defer file.Close()
m.PushNoticeGrow(kit.Format("%v %v %v\n", header.Name, kit.FmtSize(f.Size()), kit.FmtSize(total)))
- if _, err = io.Copy(t, file); m.Warn(err != nil, "err: %v", err) {
+ if _, err = io.Copy(t, file); m.Warn(err) {
return
}
@@ -84,5 +84,5 @@ func init() {
}
m.StatusTimeCountTotal(kit.FmtSize(total))
}},
- }})
+ })
}
diff --git a/base/nfs/trash.go b/base/nfs/trash.go
index 6eb10f24..8c291eac 100644
--- a/base/nfs/trash.go
+++ b/base/nfs/trash.go
@@ -1,7 +1,6 @@
package nfs
import (
- "os"
"path"
ice "shylinux.com/x/icebergs"
@@ -10,61 +9,59 @@ import (
)
func _trash_create(m *ice.Message, name string) {
- if s, e := os.Stat(name); m.Assert(e) {
- p := path.Join(ice.VAR_TRASH, path.Base(name))
- if !s.IsDir() {
- if f, e := os.Open(name); m.Assert(e) {
- defer f.Close()
- p = path.Join(ice.VAR_TRASH, kit.HashsPath(f))
- }
+ if m.Warn(name == "", ice.ErrNotValid, name) {
+ return
+ }
+ s, e := StatFile(m, name)
+ if m.Warn(e, ice.ErrNotFound, name) {
+ return
+ }
+ p := path.Join(ice.VAR_TRASH, path.Base(name))
+ if !s.IsDir() {
+ if f, e := OpenFile(m, name); m.Assert(e) {
+ defer f.Close()
+ p = path.Join(ice.VAR_TRASH, kit.HashsPath(f))
}
+ }
- MkdirAll(m, path.Dir(p))
- if os.RemoveAll(p); !m.Warn(os.Rename(name, p)) {
- m.Cmd(mdb.INSERT, TRASH, "", mdb.HASH, FILE, p, FROM, name)
- }
+ MkdirAll(m, path.Dir(p))
+ if RemoveAll(m, p); !m.Warn(Rename(m, name, p)) {
+ mdb.HashCreate(m, FROM, name, FILE, p)
}
}
-const (
- FROM = "from"
-)
const TRASH = "trash"
func init() {
- Index.Merge(&ice.Context{Configs: ice.Configs{
- TRASH: {Name: TRASH, Help: "回收站", Value: kit.Data(
- mdb.SHORT, FROM, mdb.FIELD, "time,hash,file,from", PATH, ice.VAR_TRASH,
- )},
- }, Commands: ice.Commands{
+ Index.MergeCommands(ice.Commands{
TRASH: {Name: "trash hash auto prunes", Help: "回收站", Actions: ice.MergeAction(ice.Actions{
mdb.REVERT: {Name: "revert", Help: "恢复", Hand: func(m *ice.Message, arg ...string) {
- os.Rename(m.Option(FILE), m.Option(FROM))
- m.Cmd(mdb.DELETE, TRASH, "", mdb.HASH, m.OptionSimple(mdb.HASH))
+ Rename(m, m.Option(FILE), m.Option(FROM))
+ mdb.HashRemove(m, m.OptionSimple(mdb.HASH))
}},
mdb.CREATE: {Name: "create path", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
- p := path.Join(m.Config(PATH), path.Base(m.Option(PATH)))
- os.RemoveAll(p)
- if os.MkdirAll(path.Dir(p), ice.MOD_DIR); !m.Warn(os.Rename(m.Option(PATH), p)) {
+ p := path.Join(ice.VAR_TRASH, path.Base(m.Option(PATH)))
+ RemoveAll(m, p)
+ if MkdirAll(m, path.Dir(p)); !m.Warn(Rename(m, m.Option(PATH), p)) {
m.Echo(p)
}
}},
mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
- os.Remove(m.Option(FILE))
- m.Cmd(mdb.DELETE, TRASH, "", mdb.HASH, m.OptionSimple(mdb.HASH))
+ Remove(m, m.Option(FILE))
+ mdb.HashRemove(m, m.OptionSimple(mdb.HASH))
}},
mdb.PRUNES: {Name: "prunes before@date", Help: "清理", Hand: func(m *ice.Message, arg ...string) {
mdb.HashPrunes(m, func(value ice.Maps) bool {
- os.Remove(value[FILE])
+ Remove(m, value[FILE])
return false
})
}},
- }, mdb.HashAction()), Hand: func(m *ice.Message, arg ...string) {
- if mdb.HashSelect(m, arg...); len(arg) == 0 || !kit.FileExists(arg[0]) {
+ }, mdb.HashAction(mdb.SHORT, FROM, mdb.FIELD, "time,hash,file,from")), Hand: func(m *ice.Message, arg ...string) {
+ if mdb.HashSelect(m, arg...); len(arg) == 0 || !ExistsFile(m, arg[0]) {
m.PushAction(mdb.REVERT, mdb.REMOVE)
return
}
_trash_create(m, arg[0])
}},
- }})
+ })
}
diff --git a/base/ssh/scripts.go b/base/ssh/scripts.go
index 26b1fed5..a42a2c0c 100644
--- a/base/ssh/scripts.go
+++ b/base/ssh/scripts.go
@@ -13,21 +13,21 @@ import (
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/cli"
"shylinux.com/x/icebergs/base/ctx"
+ "shylinux.com/x/icebergs/base/gdb"
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/nfs"
kit "shylinux.com/x/toolkits"
)
-func Render(msg *ice.Message, cmd string, args ...ice.Any) (res string) {
- switch arg := kit.Simple(args...); cmd {
+func Render(msg *ice.Message, cmd string, arg ...ice.Any) (res string) {
+ switch args := kit.Simple(arg...); cmd {
case ice.RENDER_VOID:
return res
case ice.RENDER_RESULT:
- if len(arg) > 0 {
- msg.Resultv(arg)
+ if len(args) > 0 {
+ msg.Resultv(args)
}
res = msg.Result()
-
default:
if res = msg.Result(); res == "" {
res = msg.Table().Result()
@@ -110,22 +110,18 @@ func (f *Frame) alias(m *ice.Message, ls []string) []string {
return ls
}
func (f *Frame) parse(m *ice.Message, line string) string {
- // for _, one := range kit.Split(line, ";", ";", ";") {
- for _, one := range kit.Simple(line) {
- msg := m.Spawn(f.target)
- ls := f.change(msg, f.alias(msg, kit.Split(strings.TrimSpace(one))))
- if len(ls) == 0 {
- continue
- }
-
- msg.Render("", kit.List())
- if msg.Cmdy(ls[0], ls[1:]); msg.IsErrNotFound() {
- msg.SetResult().Cmdy(cli.SYSTEM, ls)
- }
-
- f.res = Render(msg, msg.Option(ice.MSG_OUTPUT), msg.Optionv(ice.MSG_ARGS).([]ice.Any)...)
+ msg := m.Spawn(f.target)
+ ls := f.change(msg, f.alias(msg, kit.Split(strings.TrimSpace(line))))
+ if len(ls) == 0 {
+ return ""
}
- m.Sleep("10ms")
+
+ msg.Render("", kit.List())
+ if msg.Cmdy(ls); 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 ""
}
func (f *Frame) scan(m *ice.Message, h, line string) *Frame {
@@ -142,22 +138,14 @@ func (f *Frame) scan(m *ice.Message, h, line string) *Frame {
m.I, m.O = f.stdin, f.stdout
bio := bufio.NewScanner(f.stdin)
- for f.prompt(m, ps...); bio.Scan() && f.stdin != nil; f.prompt(m, ps...) {
- if h == STDIO {
- if len(bio.Text()) == 0 {
- continue // 空行
- }
- m.Cmdx(mdb.INSERT, SOURCE, kit.Keys(mdb.HASH, h), mdb.LIST, mdb.TEXT, bio.Text())
+ for f.prompt(m, ps...); f.stdin != nil && bio.Scan(); f.prompt(m, ps...) {
+ if len(bio.Text()) == 0 && h == STDIO {
+ continue // 空行
}
f.count++
+ mdb.ZoneInsert(m.Spawn(), mdb.HASH, h, mdb.TEXT, bio.Text())
- if len(bio.Text()) == 0 {
- if strings.Count(line, "`")%2 == 1 {
- line += ice.NL
- }
- continue // 空行
- }
if strings.HasSuffix(bio.Text(), "\\") {
line += bio.Text()[:len(bio.Text())-1]
ps = f.ps2
@@ -170,11 +158,8 @@ func (f *Frame) scan(m *ice.Message, h, line string) *Frame {
}
if strings.HasPrefix(strings.TrimSpace(line), "#") {
line = ""
- continue
+ continue // 注释
}
- // if line = strings.Split(line, " # ")[0]; len(line) == 0 {
- // continue // 注释
- // }
if ps = f.ps1; f.stdout == os.Stdout {
if ice.Info.Colors {
f.printf(m, "\033[0m") // 清空格式
@@ -195,27 +180,28 @@ func (f *Frame) Start(m *ice.Message, arg ...string) bool {
m.Optionv(FRAME, f)
switch f.source = kit.Select(STDIO, arg, 0); f.source {
case STDIO: // 终端交互
- m.Cap(ice.CTX_STREAM, f.source)
- if f.target == nil {
+ if m.Cap(ice.CTX_STREAM, f.source); f.target == nil {
f.target = m.Target()
}
r, w, _ := os.Pipe()
- m.Go(func() { io.Copy(w, os.Stdin) })
- f.stdin, f.stdout = r, os.Stdout
- f.pipe = w
+ go func() { io.Copy(w, os.Stdin) }()
+ f.pipe, f.stdin, f.stdout = w, r, os.Stdout
m.Option(ice.MSG_OPTS, ice.MSG_USERNAME)
-
m.Conf(SOURCE, kit.Keys(mdb.HASH, STDIO, kit.Keym(mdb.NAME)), STDIO)
m.Conf(SOURCE, kit.Keys(mdb.HASH, STDIO, kit.Keym(mdb.TIME)), m.Time())
-
f.count = kit.Int(m.Conf(SOURCE, kit.Keys(mdb.HASH, STDIO, kit.Keym(mdb.COUNT)))) + 1
f.scan(m, STDIO, "")
default: // 脚本文件
- if strings.Contains(m.Option(ice.MSG_SCRIPT), ice.PS) {
- f.source = path.Join(path.Dir(m.Option(ice.MSG_SCRIPT)), f.source)
+ if m.Option(ice.MSG_SCRIPT) != "" {
+ ls := kit.Split(m.Option(ice.MSG_SCRIPT), ice.PS)
+ for i := len(ls) - 1; i > 0; i-- {
+ if p := path.Join(path.Join(ls[:i]...), f.source); nfs.ExistsFile(m, p) {
+ f.source = p
+ }
+ }
}
m.Option(ice.MSG_SCRIPT, f.source)
f.target = m.Source()
@@ -224,13 +210,12 @@ func (f *Frame) Start(m *ice.Message, arg ...string) bool {
return true // 查找失败
} else {
buf := bytes.NewBuffer(make([]byte, 0, ice.MOD_BUFS))
+ f.stdin, f.stdout = bytes.NewBufferString(msg.Result()), buf
defer func() { m.Echo(buf.String()) }()
-
- f.stdin, f.stdout = bytes.NewBuffer([]byte(msg.Result())), buf
}
f.count = 1
- f.scan(m, m.Cmdx(mdb.INSERT, SOURCE, "", mdb.HASH, mdb.NAME, f.source), "")
+ f.scan(m, mdb.HashCreate(m.Spawn(), mdb.NAME, f.source).Result(), "")
}
return true
}
@@ -266,16 +251,14 @@ func init() {
PS2, []ice.Any{mdb.COUNT, " ", TARGET, "> "},
)},
}, Commands: ice.Commands{
- ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {}},
SOURCE: {Name: "source file", Help: "脚本解析", Actions: ice.MergeAction(ice.Actions{
- "repeat": {Name: "repeat", Help: "执行", Hand: func(m *ice.Message, arg ...string) {
+ gdb.RESTART: {Name: "restart", Help: "执行", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(SCREEN, m.Option(mdb.TEXT))
m.ProcessInner()
}},
}, mdb.ZoneAction()), Hand: func(m *ice.Message, arg ...string) {
- if len(arg) > 0 && kit.Ext(arg[0]) == ice.SHY {
- (&Frame{}).Start(m, arg...)
- return // 脚本解析
+ if f, ok := m.Target().Server().(*Frame); ok {
+ f.Spawn(m, m.Target()).Start(m, arg...)
}
}},
TARGET: {Name: "target name run", Help: "当前模块", Hand: func(m *ice.Message, arg ...string) {
@@ -284,26 +267,30 @@ func init() {
f.prompt(m)
}},
PROMPT: {Name: "prompt arg run", Help: "命令提示", Hand: func(m *ice.Message, arg ...string) {
- f := m.Optionv(FRAME).(*Frame)
- f.ps1 = arg
- f.prompt(m)
+ if f, ok := m.Optionv(FRAME).(*Frame); ok {
+ f.ps1 = arg
+ f.prompt(m)
+ }
}},
PRINTF: {Name: "printf run text", Help: "输出显示", Hand: func(m *ice.Message, arg ...string) {
- f := m.Optionv(FRAME).(*Frame)
- f.printf(m, arg[0])
+ if f, ok := m.Optionv(FRAME).(*Frame); ok {
+ f.printf(m, arg[0])
+ }
}},
SCREEN: {Name: "screen run text", Help: "输出命令", Hand: func(m *ice.Message, arg ...string) {
- f := m.Optionv(FRAME).(*Frame)
- for _, line := range kit.Split(arg[0], ice.NL, ice.NL) {
- fmt.Fprintf(f.pipe, line+ice.NL)
- f.printf(m, line+ice.NL)
- m.Sleep300ms()
+ if f, ok := m.Optionv(FRAME).(*Frame); ok {
+ for _, line := range kit.Split(arg[0], ice.NL, ice.NL) {
+ fmt.Fprintf(f.pipe, line+ice.NL)
+ f.printf(m, line+ice.NL)
+ m.Sleep300ms()
+ }
+ m.Echo(f.res)
}
- m.Echo(f.res)
}},
RETURN: {Name: "return", Help: "结束脚本", Hand: func(m *ice.Message, arg ...string) {
- f := m.Optionv(FRAME).(*Frame)
- f.Close(m, arg...)
+ if f, ok := m.Optionv(FRAME).(*Frame); ok {
+ f.Close(m, arg...)
+ }
}},
}})
}
diff --git a/base/tcp/client.go b/base/tcp/client.go
index 12b20db4..8d65700d 100644
--- a/base/tcp/client.go
+++ b/base/tcp/client.go
@@ -36,7 +36,6 @@ func (c *Conn) Close() error {
func _client_dial(m *ice.Message, arg ...string) {
c, e := net.Dial(TCP, m.Option(HOST)+ice.DF+m.Option(PORT))
-
c = &Conn{m: m, s: &Stat{}, Conn: c}
if e == nil {
defer c.Close()
@@ -57,8 +56,10 @@ func _client_dial(m *ice.Message, arg ...string) {
break
}
}
- default:
+ case nil:
c.Write([]byte("hello world\n"))
+ default:
+ m.ErrorNotImplement(cb)
}
}
@@ -77,25 +78,18 @@ const (
const CLIENT = "client"
func init() {
- Index.Merge(&ice.Context{Configs: ice.Configs{
- CLIENT: {Name: CLIENT, Help: "客户端", Value: kit.Data(
- mdb.FIELD, "time,hash,status,type,name,host,port,error,nread,nwrite",
- )},
- }, Commands: ice.Commands{
+ Index.MergeCommands(ice.Commands{
CLIENT: {Name: "client hash auto prunes", Help: "客户端", Actions: ice.MergeAction(ice.Actions{
ice.CTX_EXIT: {Hand: func(m *ice.Message, arg ...string) {
- m.Richs(CLIENT, "", mdb.FOREACH, func(key string, value ice.Map) {
- kit.Value(value, kit.Keym(STATUS), CLOSE)
- })
- m.Cmdy(SERVER, mdb.PRUNES)
+ m.Conf(m.PrefixKey(), "", "")
}},
DIAL: {Name: "dial type name port=9010 host=", Help: "连接", Hand: func(m *ice.Message, arg ...string) {
_client_dial(m, arg...)
}},
- }, mdb.HashActionStatus()), Hand: func(m *ice.Message, arg ...string) {
+ }, mdb.HashActionStatus(mdb.FIELD, "time,hash,status,type,name,host,port,error,nread,nwrite")), Hand: func(m *ice.Message, arg ...string) {
mdb.HashSelect(m, arg...).Tables(func(value ice.Maps) {
m.PushButton(kit.Select("", mdb.REMOVE, value[STATUS] == OPEN))
})
}},
- }})
+ })
}
diff --git a/base/tcp/host.go b/base/tcp/host.go
index 15562e9a..cd6ac8a0 100644
--- a/base/tcp/host.go
+++ b/base/tcp/host.go
@@ -59,13 +59,6 @@ func _islocalhost(m *ice.Message, ip string) (ok bool) {
}
return false
}
-func IsLocalHost(m *ice.Message, ip string) bool { return _islocalhost(m, ip) }
-func ReplaceLocalhost(m *ice.Message, url string) string {
- if strings.Contains(url, "://"+LOCALHOST) {
- url = strings.Replace(url, "://"+LOCALHOST, "://"+m.Cmd(HOST).Append(aaa.IP), 1)
- }
- return url
-}
const (
LOCALHOST = "localhost"
@@ -73,16 +66,10 @@ const (
const HOST = "host"
func init() {
- Index.Merge(&ice.Context{Configs: ice.Configs{
- HOST: {Name: HOST, Help: "主机", Value: kit.Data(
- aaa.BLACK, kit.Data(mdb.SHORT, mdb.TEXT), aaa.WHITE, kit.Data(mdb.SHORT, mdb.TEXT),
- )},
- }, Commands: ice.Commands{
- HOST: {Name: "host name auto", Help: "主机", Actions: ice.Actions{
+ Index.MergeCommands(ice.Commands{
+ HOST: {Name: "host name auto", Help: "主机", Actions: ice.MergeAction(ice.Actions{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
- m.Cmd(HOST).Tables(func(value ice.Maps) {
- m.Cmd(HOST, aaa.WHITE, value[aaa.IP])
- })
+ m.Cmd(HOST).Tables(func(value ice.Maps) { m.Cmd(HOST, aaa.WHITE, value[aaa.IP]) })
}},
aaa.BLACK: {Name: "black", Help: "黑名单", Hand: func(m *ice.Message, arg ...string) {
m.Log_CREATE(aaa.BLACK, arg[0])
@@ -92,8 +79,16 @@ func init() {
m.Log_CREATE(aaa.WHITE, arg[0])
m.Rich(HOST, kit.Keym(aaa.WHITE), kit.Dict(mdb.TEXT, arg[0]))
}},
- }, Hand: func(m *ice.Message, arg ...string) {
+ }, mdb.HashAction(aaa.BLACK, kit.Data(mdb.SHORT, mdb.TEXT), aaa.WHITE, kit.Data(mdb.SHORT, mdb.TEXT))), Hand: func(m *ice.Message, arg ...string) {
_host_list(m, kit.Select("", arg, 0))
}},
- }})
+ })
+}
+
+func IsLocalHost(m *ice.Message, ip string) bool { return _islocalhost(m, ip) }
+func ReplaceLocalhost(m *ice.Message, url string) string {
+ if strings.Contains(url, "://"+LOCALHOST) {
+ url = strings.Replace(url, "://"+LOCALHOST, "://"+m.Cmd(HOST).Append(aaa.IP), 1)
+ }
+ return url
}
diff --git a/base/tcp/port.go b/base/tcp/port.go
index 314ee475..e52cbf88 100644
--- a/base/tcp/port.go
+++ b/base/tcp/port.go
@@ -6,7 +6,6 @@ import (
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/aaa"
- "shylinux.com/x/icebergs/base/cli"
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/nfs"
kit "shylinux.com/x/toolkits"
@@ -25,12 +24,12 @@ func _port_right(m *ice.Message, arg ...string) string {
c.Close()
continue
}
- p := path.Join(m.Conf(cli.DAEMON, kit.Keym(nfs.PATH)), kit.Format(i))
- if kit.FileExists(p) {
+ p := path.Join(ice.USR_LOCAL_DAEMON, kit.Format(i))
+ if nfs.ExistsFile(m, p) {
continue
}
- nfs.MkdirAll(m, p)
+ nfs.MkdirAll(m, p)
m.Log_SELECT(PORT, i)
return m.Config(CURRENT, i)
}
@@ -46,10 +45,8 @@ const (
const PORT = "port"
func init() {
- Index.Merge(&ice.Context{Configs: ice.Configs{
- PORT: {Name: PORT, Help: "端口", Value: kit.Data(BEGIN, 10000, CURRENT, 10000, END, 20000)},
- }, Commands: ice.Commands{
- PORT: {Name: "port port path auto", Help: "端口", Actions: ice.Actions{
+ Index.MergeCommands(ice.Commands{
+ PORT: {Name: "port port path auto", Help: "端口", Actions: ice.MergeAction(ice.Actions{
aaa.RIGHT: {Name: "right", Help: "分配", Hand: func(m *ice.Message, arg ...string) {
m.Echo(_port_right(m, arg...))
}},
@@ -58,33 +55,33 @@ func init() {
m.Cmd(nfs.TRASH, path.Join(ice.USR_LOCAL_DAEMON, m.Option(PORT)))
}
}},
- }, Hand: func(m *ice.Message, arg ...string) {
- if len(arg) == 0 {
- current := kit.Int(m.Config(BEGIN))
- m.Option(nfs.DIR_ROOT, ice.USR_LOCAL_DAEMON)
- m.Cmd(nfs.DIR, nfs.PWD, nfs.DIR_CLI_FIELDS).Tables(func(value ice.Maps) {
- bin := m.Cmd(nfs.DIR, path.Join(value[nfs.PATH], ice.BIN), nfs.DIR_CLI_FIELDS).Append(nfs.PATH)
- if bin == "" {
- bin = m.Cmd(nfs.DIR, path.Join(value[nfs.PATH], "sbin"), nfs.DIR_CLI_FIELDS).Append(nfs.PATH)
- }
- port := kit.Int(path.Base(value[nfs.PATH]))
- if port > current {
- current = port
- }
-
- m.Push(mdb.TIME, value[mdb.TIME])
- m.Push(PORT, port)
- m.Push(nfs.SIZE, value[nfs.SIZE])
- m.Push(ice.BIN, bin)
- })
- m.SortInt(PORT)
- m.PushAction(nfs.TRASH)
- m.Config(CURRENT, current)
- m.StatusTimeCount(m.ConfigSimple(BEGIN, CURRENT, END))
+ }, mdb.HashAction(BEGIN, 10000, CURRENT, 10000, END, 20000)), Hand: func(m *ice.Message, arg ...string) {
+ if len(arg) > 0 {
+ m.Cmdy(nfs.DIR, arg[1:], kit.Dict(nfs.DIR_ROOT, path.Join(ice.USR_LOCAL_DAEMON, arg[0])))
return
}
- m.Option(nfs.DIR_ROOT, path.Join(m.Conf(cli.DAEMON, kit.Keym(nfs.PATH)), arg[0]))
- m.Cmdy(nfs.DIR, arg[1:])
+
+ current := kit.Int(m.Config(BEGIN))
+ m.Option(nfs.DIR_ROOT, ice.USR_LOCAL_DAEMON)
+ m.Cmd(nfs.DIR, nfs.PWD, nfs.DIR_CLI_FIELDS).Tables(func(value ice.Maps) {
+ bin := m.Cmd(nfs.DIR, path.Join(value[nfs.PATH], ice.BIN), nfs.DIR_CLI_FIELDS).Append(nfs.PATH)
+ if bin == "" {
+ bin = m.Cmd(nfs.DIR, path.Join(value[nfs.PATH], "sbin"), nfs.DIR_CLI_FIELDS).Append(nfs.PATH)
+ }
+ port := kit.Int(path.Base(value[nfs.PATH]))
+ if port > current {
+ current = port
+ }
+
+ m.Push(mdb.TIME, value[mdb.TIME])
+ m.Push(PORT, port)
+ m.Push(nfs.SIZE, value[nfs.SIZE])
+ m.Push(ice.BIN, bin)
+ })
+ m.SortInt(PORT)
+ m.PushAction(nfs.TRASH)
+ m.Config(CURRENT, current)
+ m.StatusTimeCount(m.ConfigSimple(BEGIN, CURRENT, END))
}},
- }})
+ })
}
diff --git a/base/tcp/server.go b/base/tcp/server.go
index 9bd7566a..1030b122 100644
--- a/base/tcp/server.go
+++ b/base/tcp/server.go
@@ -19,7 +19,7 @@ type Listener struct {
func (l Listener) Accept() (net.Conn, error) {
c, e := l.Listener.Accept()
l.s.nc += 1
- return &Conn{m: l.m, h: "", s: &Stat{}, Conn: c}, e
+ return &Conn{m: l.m, s: &Stat{}, Conn: c}, e
}
func (l Listener) Close() error {
l.m.Cmd(mdb.MODIFY, SERVER, "", mdb.HASH, mdb.HASH, l.h, STATUS, CLOSE)
@@ -28,10 +28,8 @@ func (l Listener) Close() error {
func _server_listen(m *ice.Message, arg ...string) {
l, e := net.Listen(TCP, m.Option(HOST)+":"+m.Option(PORT))
- h := m.Cmdx(mdb.INSERT, SERVER, "", mdb.HASH, arg,
- STATUS, kit.Select(ERROR, OPEN, e == nil), ERROR, kit.Format(e))
-
- l = &Listener{m: m, h: h, s: &Stat{}, Listener: l}
+ l = &Listener{m: m, h: m.Cmdx(mdb.INSERT, SERVER, "", mdb.HASH,
+ arg, STATUS, kit.Select(ERROR, OPEN, e == nil), ERROR, kit.Format(e), kit.Dict(mdb.TARGET, l)), s: &Stat{}, Listener: l}
if e == nil {
defer l.Close()
}
@@ -85,25 +83,28 @@ const (
const SERVER = "server"
func init() {
- Index.Merge(&ice.Context{Configs: ice.Configs{
- SERVER: {Name: SERVER, Help: "服务器", Value: kit.Data(
- mdb.FIELD, "time,hash,status,type,name,host,port,error,nconn",
- )},
- }, Commands: ice.Commands{
+ Index.MergeCommands(ice.Commands{
SERVER: {Name: "server hash auto prunes", Help: "服务器", Actions: ice.MergeAction(ice.Actions{
+ ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
+ m.Conf("", mdb.HASH, "")
+ }},
ice.CTX_EXIT: {Hand: func(m *ice.Message, arg ...string) {
- m.Richs(SERVER, "", mdb.FOREACH, func(key string, value ice.Map) {
- kit.Value(value, kit.Keym(STATUS), CLOSE)
+ mdb.HashSelectValue(m, func(target ice.Any) {
+ if l, ok := target.(net.Listener); ok {
+ l.Close()
+ }
+ if l, ok := target.(*Listener); ok {
+ l.Close()
+ }
})
- m.Cmdy(SERVER, mdb.PRUNES)
}},
LISTEN: {Name: "LISTEN type name port=9030 host=", Help: "监听", Hand: func(m *ice.Message, arg ...string) {
_server_listen(m, arg...)
}},
- }, mdb.HashActionStatus()), Hand: func(m *ice.Message, arg ...string) {
+ }, mdb.HashActionStatus(mdb.FIELD, "time,hash,status,type,name,host,port,error,nconn")), Hand: func(m *ice.Message, arg ...string) {
mdb.HashSelect(m, arg...).Tables(func(value ice.Maps) {
m.PushButton(kit.Select("", mdb.REMOVE, value[STATUS] == CLOSE))
})
}},
- }})
+ })
}
diff --git a/base/web/story.go b/base/web/_story.go
similarity index 99%
rename from base/web/story.go
rename to base/web/_story.go
index 98c76ba7..7b75cd79 100644
--- a/base/web/story.go
+++ b/base/web/_story.go
@@ -426,5 +426,4 @@ func _story_commit(m *ice.Message, arg ...string) {
value["list"] = list
}
m.Echo(list)
-
}
diff --git a/base/web/broad.go b/base/web/broad.go
index 729cb8b5..21fa678d 100644
--- a/base/web/broad.go
+++ b/base/web/broad.go
@@ -5,85 +5,86 @@ import (
"strings"
ice "shylinux.com/x/icebergs"
+ "shylinux.com/x/icebergs/base/aaa"
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/tcp"
kit "shylinux.com/x/toolkits"
)
-func _udp_addr(m *ice.Message, host, port string) *net.UDPAddr {
+func _broad_addr(m *ice.Message, host, port string) *net.UDPAddr {
addr, err := net.ResolveUDPAddr("udp4", kit.Format("%s:%s", host, port))
m.Assert(err)
return addr
}
-func _udp_broad(m *ice.Message, host, port string, remote_host, remote_port string) {
- if s, e := net.DialUDP("udp", nil, _udp_addr(m, remote_host, remote_port)); m.Assert(e) {
+func _broad_send(m *ice.Message, host, port string, remote_host, remote_port string) {
+ if s, e := net.DialUDP("udp", nil, _broad_addr(m, remote_host, remote_port)); m.Assert(e) {
defer s.Close()
msg := m.Spawn(kit.Dict(tcp.HOST, host, tcp.PORT, port))
- m.Debug("broad %v to %v:%v", msg.FormatMeta(), remote_host, remote_port)
+ m.Log_EXPORT(BROAD, msg.FormatMeta(), "to", remote_host+ice.DF+remote_port)
s.Write([]byte(msg.FormatMeta()))
}
}
-func _serve_udp(m *ice.Message, host, port string) {
- m.Cmd(BROAD, mdb.CREATE, tcp.HOST, host, tcp.PORT, port)
- _udp_broad(m, host, port, "255.255.255.255", "9020")
-
- if s, e := net.ListenUDP("udp", _udp_addr(m, "0.0.0.0", port)); m.Assert(e) {
+func _broad_serve(m *ice.Message, host, port string) {
+ _broad_send(m, host, port, "255.255.255.255", "9020")
+ if s, e := net.ListenUDP("udp", _broad_addr(m, "0.0.0.0", port)); m.Assert(e) {
defer s.Close()
- m.Debug("listen %v %v", host, port)
+ m.Cmd(BROAD, mdb.CREATE, tcp.HOST, host, tcp.PORT, port, kit.Dict(mdb.TARGET, s))
- buf := make([]byte, 1024)
+ buf := make([]byte, ice.MOD_BUFS)
for {
n, addr, err := s.ReadFromUDP(buf[:])
if err != nil {
- m.Debug("what %v", err)
- continue
+ break
}
- m.Debug("recv %v %v", string(buf[:n]), addr)
+ m.Log_IMPORT(BROAD, string(buf[:n]), "from", addr)
msg := m.Spawn(buf[:n])
if m.Cmd(BROAD, kit.Format("%s,%s", msg.Option(tcp.HOST), msg.Option(tcp.PORT))).Length() > 0 {
continue
}
- if remote, err := net.ResolveUDPAddr("udp4", kit.Format("%s:%s", msg.Option(tcp.HOST), msg.Option(tcp.PORT))); err == nil {
+ if remote, err := net.ResolveUDPAddr("udp4", kit.Format("%s:%s", msg.Option(tcp.HOST), msg.Option(tcp.PORT))); !m.Warn(err) {
m.Cmd(BROAD).Tables(func(value ice.Maps) {
- m.Debug("broad %v to %v", kit.Format(value), kit.Format(remote))
+ m.Log_EXPORT(BROAD, kit.Format(value), "to", kit.Format(remote))
s.WriteToUDP([]byte(m.Spawn(value).FormatMeta()), remote)
})
m.Cmd(BROAD, mdb.CREATE, msg.OptionSimple(tcp.HOST, tcp.PORT))
- } else {
- m.Debug("what %v", err)
}
}
}
}
func _broad_search(m *ice.Message, kind, name, text string, arg ...string) {
- m.Richs(BROAD, nil, mdb.FOREACH, func(key string, value ice.Map) {
- if value = kit.GetMeta(value); !strings.Contains(kit.Format(value[tcp.HOST]), name) {
+ mdb.HashSelectValue(m, func(value ice.Map) {
+ if !strings.Contains(kit.Format(value[tcp.HOST]), name) {
return
}
- m.PushSearch(mdb.TYPE, "friend", mdb.TEXT, kit.Format("http://%s:%s", value[tcp.HOST], value[tcp.PORT]), value)
+ m.PushSearch(mdb.TYPE, FRIEND, mdb.TEXT, kit.Format("http://%s:%s", value[tcp.HOST], value[tcp.PORT]), value)
})
}
const BROAD = "broad"
func init() {
- Index.Merge(&ice.Context{Commands: ice.Commands{
- BROAD: {Name: "broad hash auto", Help: "广播", Actions: ice.MergeAction(ice.Actions{
+ Index.MergeCommands(ice.Commands{
+ BROAD: {Name: "broad hash auto serve", Help: "广播", Actions: ice.MergeAction(ice.Actions{
+ ice.CTX_EXIT: {Hand: func(m *ice.Message, arg ...string) {
+ mdb.HashSelectValue(m, func(target ice.Any) {
+ if c, ok := target.(*net.UDPConn); ok {
+ c.Close()
+ }
+ })
+ }},
+ mdb.SEARCH: {Name: "search type name text", Help: "搜索", Hand: func(m *ice.Message, arg ...string) {
+ _broad_search(m, arg[0], arg[1], kit.Select("", arg, 2))
+ }},
SERVE: {Name: "broad port=9020", Help: "搜索", Hand: func(m *ice.Message, arg ...string) {
- _serve_udp(m, m.Cmd(tcp.HOST).Append("ip"), m.Option(tcp.PORT))
+ _broad_serve(m, m.Cmd(tcp.HOST).Append(aaa.IP), m.Option(tcp.PORT))
}},
SPACE: {Name: "space dev", Help: "连接", Hand: func(m *ice.Message, arg ...string) {
m.Cmd(SPIDE, mdb.CREATE, mdb.NAME, m.Option(ice.DEV), ADDRESS,
kit.Format("http://%s:%s", m.Option(tcp.HOST), m.Option(tcp.PORT)))
m.Cmd(SPACE, tcp.DIAL, m.OptionSimple(ice.DEV))
}},
- }, mdb.HashAction(
- mdb.SHORT, "host,port", mdb.FIELD, "time,hash,host,port",
- )), Hand: func(m *ice.Message, arg ...string) {
- mdb.HashSelect(m, arg...)
- m.PushAction(SPACE, mdb.REMOVE)
- }},
- }})
+ }, mdb.HashAction(mdb.SHORT, "host,port", mdb.FIELD, "time,hash,host,port", mdb.ACTION, "space"))},
+ })
}
diff --git a/base/web/cache.go b/base/web/cache.go
index 0fed59d7..2bc4bfc4 100644
--- a/base/web/cache.go
+++ b/base/web/cache.go
@@ -10,16 +10,17 @@ import (
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/nfs"
kit "shylinux.com/x/toolkits"
+ "shylinux.com/x/toolkits/miss"
)
func _cache_name(m *ice.Message, h string) string {
- return path.Join(m.Config(nfs.PATH), h[:2], h)
+ return path.Join(ice.VAR_FILE, h[:2], h)
}
func _cache_save(m *ice.Message, kind, name, text string, arg ...string) { // file size
if name == "" {
return
}
- if len(text) > 512 || kind == "go" { // 存入文件
+ if len(text) > 512 || kind == nfs.GO { // 存入文件
p := m.Cmdx(nfs.SAVE, _cache_name(m, kit.Hashs(text)), text)
text, arg = p, kit.Simple(p, len(text))
}
@@ -28,7 +29,7 @@ func _cache_save(m *ice.Message, kind, name, text string, arg ...string) { // fi
size := kit.Int(kit.Select(kit.Format(len(text)), arg, 1))
file := kit.Select("", arg, 0)
text = kit.Select(file, text)
- h := m.Cmdx(mdb.INSERT, CACHE, "", mdb.HASH, kit.SimpleKV("", kind, name, text), nfs.FILE, file, nfs.SIZE, size)
+ h := mdb.HashCreate(m, kit.SimpleKV("", kind, name, text), nfs.FILE, file, nfs.SIZE, size).Result()
// 返回结果
m.Push(mdb.TIME, m.Time())
@@ -50,26 +51,26 @@ func _cache_watch(m *ice.Message, key, file string) {
})
}
func _cache_catch(m *ice.Message, name string) (file, size string) {
- if f, e := os.Open(name); m.Assert(e) {
+ if f, e := nfs.OpenFile(m, name); m.Assert(e) {
defer f.Close()
- if s, e := f.Stat(); m.Assert(e) {
+ if s, e := nfs.StatFile(m, name); m.Assert(e) {
return m.Cmdx(nfs.LINK, _cache_name(m, kit.Hashs(f)), name), kit.Format(s.Size())
}
}
return "", "0"
}
func _cache_upload(m *ice.Message, r *http.Request) (kind, name, file, size string) {
- if buf, h, e := r.FormFile(UPLOAD); e == nil {
- defer buf.Close()
+ if b, h, e := r.FormFile(UPLOAD); e == nil {
+ defer b.Close()
// 创建文件
- if f, p, e := kit.Create(_cache_name(m, kit.Hashs(buf))); m.Assert(e) {
+ if f, p, e := miss.CreateFile(_cache_name(m, kit.Hashs(b))); m.Assert(e) {
defer f.Close()
// 导入数据
- buf.Seek(0, os.SEEK_SET)
- if n, e := io.Copy(f, buf); m.Assert(e) {
+ b.Seek(0, os.SEEK_SET)
+ if n, e := io.Copy(f, b); m.Assert(e) {
m.Log_IMPORT(nfs.FILE, p, nfs.SIZE, kit.FmtSize(int64(n)))
return h.Header.Get(ContentType), h.Filename, p, kit.Format(n)
}
@@ -80,12 +81,14 @@ func _cache_upload(m *ice.Message, r *http.Request) (kind, name, file, size stri
func _cache_download(m *ice.Message, r *http.Response) (file, size string) {
defer r.Body.Close()
- if f, p, e := kit.Create(path.Join(ice.VAR_TMP, kit.Hashs(mdb.UNIQ))); m.Assert(e) {
- step, total := 0, kit.Int(kit.Select("1", r.Header.Get(ContentLength)))
+ if f, p, e := miss.CreateFile(path.Join(ice.VAR_TMP, kit.Hashs(mdb.UNIQ))); m.Assert(e) {
+ defer f.Close()
+
+ step, total := 0, kit.Int(kit.Select("100", r.Header.Get(ContentLength)))
size, buf := 0, make([]byte, ice.MOD_BUFS)
for {
- if n, _ := r.Body.Read(buf); n > 0 {
+ if n, e := r.Body.Read(buf); n > 0 && e == nil {
size += n
f.Write(buf[0:n])
s := size * 100 / total
@@ -95,31 +98,16 @@ func _cache_download(m *ice.Message, r *http.Response) (file, size string) {
cb(size, total, s)
case func(int, int):
cb(size, total)
- case []string:
- m.Richs(cb[0], cb[1], cb[2], func(key string, value ice.Map) {
- value = kit.GetMeta(value)
- value[mdb.COUNT], value[mdb.TOTAL], value[mdb.VALUE] = size, total, kit.Format(s)
- })
default:
if s != step && s%10 == 0 {
m.Log_IMPORT(nfs.FILE, p, mdb.VALUE, s, mdb.COUNT, kit.FmtSize(int64(size)), mdb.TOTAL, kit.FmtSize(int64(total)))
}
}
+
step = s
continue
}
-
- f.Close()
- break
- }
-
- if f, e := os.Open(p); m.Assert(e) {
- defer f.Close()
-
- m.Log_IMPORT(nfs.FILE, p, nfs.SIZE, kit.FmtSize(int64(size)))
- c := _cache_name(m, kit.Hashs(f))
- m.Cmd(nfs.LINK, c, p)
- return c, kit.Format(size)
+ return p, kit.Format(size)
}
}
return "", "0"
@@ -135,22 +123,7 @@ const (
const CACHE = "cache"
func init() {
- Index.Merge(&ice.Context{Configs: ice.Configs{
- CACHE: {Name: CACHE, Help: "缓存池", Value: kit.Data(
- mdb.SHORT, mdb.TEXT, mdb.FIELD, "time,hash,size,type,name,text",
- mdb.STORE, ice.VAR_DATA, nfs.PATH, ice.VAR_FILE, mdb.FSIZE, "200000",
- mdb.LIMIT, "50", mdb.LEAST, "30",
- )},
- }, Commands: ice.Commands{
- "/cache/": {Name: "/cache/", Help: "缓存池", Hand: func(m *ice.Message, arg ...string) {
- m.Richs(CACHE, nil, arg[0], func(key string, value ice.Map) {
- if kit.Format(value[nfs.FILE]) == "" {
- m.RenderResult(value[mdb.TEXT])
- } else {
- m.RenderDownload(value[nfs.FILE])
- }
- })
- }},
+ Index.MergeCommands(ice.Commands{
CACHE: {Name: "cache hash auto", Help: "缓存池", Actions: ice.MergeAction(ice.Actions{
WATCH: {Name: "watch key file", Help: "释放", Hand: func(m *ice.Message, arg ...string) {
_cache_watch(m, arg[0], arg[1])
@@ -169,19 +142,28 @@ func init() {
DOWNLOAD: {Name: "download type name", Help: "下载", Hand: func(m *ice.Message, arg ...string) {
if r, ok := m.Optionv(RESPONSE).(*http.Response); ok {
file, size := _cache_download(m, r)
+ file, size = _cache_catch(m, file)
_cache_save(m, arg[0], arg[1], "", file, size)
}
}},
- }, mdb.HashAction()), Hand: func(m *ice.Message, arg ...string) {
+ }, mdb.HashAction(mdb.SHORT, mdb.TEXT, mdb.FIELD, "time,hash,size,type,name,text,file")), Hand: func(m *ice.Message, arg ...string) {
if mdb.HashSelect(m, arg...); len(arg) == 0 {
return
}
-
if m.Append(nfs.FILE) == "" {
m.PushScript("inner", m.Append(mdb.TEXT))
} else {
- m.PushDownload(m.Append(mdb.NAME), m.MergeURL2("/share/cache/"+arg[0]))
+ m.PushDownload(m.Append(mdb.NAME), m.MergeURL2(SHARE_CACHE+arg[0]))
}
}},
- }})
+ PP(CACHE): {Name: "/cache/", Help: "缓存池", Hand: func(m *ice.Message, arg ...string) {
+ mdb.HashSelectDetail(m, arg[0], func(value ice.Map) {
+ if kit.Format(value[nfs.FILE]) == "" {
+ m.RenderResult(value[mdb.TEXT])
+ } else {
+ m.RenderDownload(value[nfs.FILE])
+ }
+ })
+ }},
+ })
}
diff --git a/base/web/dream.go b/base/web/dream.go
index e28d092d..e12021b5 100644
--- a/base/web/dream.go
+++ b/base/web/dream.go
@@ -7,44 +7,65 @@ import (
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/cli"
- "shylinux.com/x/icebergs/base/gdb"
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/nfs"
"shylinux.com/x/icebergs/base/tcp"
kit "shylinux.com/x/toolkits"
+ "shylinux.com/x/toolkits/file"
)
func _dream_list(m *ice.Message) *ice.Message {
- return m.Cmdy(nfs.DIR, m.Config(nfs.PATH), "time,size,name").Tables(func(value ice.Maps) {
- if m.Richs(SPACE, nil, value[mdb.NAME], func(key string, val ice.Map) {
- m.Push(mdb.TYPE, val[mdb.TYPE])
+ list := m.CmdMap(SPACE, mdb.NAME)
+ m.Cmdy(nfs.DIR, ice.USR_LOCAL_WORK, "time,size,name").Tables(func(value ice.Maps) {
+ if dream, ok := list[value[mdb.NAME]]; ok {
+ m.Push(mdb.TYPE, dream[mdb.TYPE])
m.Push(cli.STATUS, cli.START)
m.PushButton("vimer", "xterm", cli.OPEN, cli.STOP)
m.PushAnchor(strings.Split(m.MergePod(value[mdb.NAME]), "?")[0])
- }) == nil {
+ text := []string{}
+ for _, line := range kit.Split(m.Cmdx(SPACE, value[mdb.NAME], cli.SYSTEM, "git", "diff", "--shortstat"), ice.FS, ice.FS) {
+ if list := kit.Split(line); strings.Contains(line, "file") {
+ text = append(text, list[0]+" file")
+ } else if strings.Contains(line, "ins") {
+ text = append(text, list[0]+" +++")
+ } else if strings.Contains(line, "dele") {
+ text = append(text, list[0]+" ---")
+ }
+ }
+ m.Push(mdb.TEXT, strings.Join(text, ", "))
+ } else {
m.Push(mdb.TYPE, WORKER)
m.Push(cli.STATUS, cli.STOP)
m.PushButton(cli.START, nfs.TRASH)
m.PushAnchor("")
+ m.Push(mdb.TEXT, "")
}
})
+ return m.Sort("status,type,name").StatusTimeCount(cli.START, len(list))
}
+
func _dream_show(m *ice.Message, name string) {
if !strings.Contains(name, "-") || !strings.HasPrefix(name, "20") {
name = m.Time("20060102-") + kit.ReplaceAll(name, "-", "_")
}
- defer m.ProcessOpen(m.MergePod(m.Option(mdb.NAME, name)))
+ // defer m.ProcessOpen(m.MergePod(m.Option(mdb.NAME, name)))
defer m.Echo(m.MergePod(m.Option(mdb.NAME, name)))
- // 任务目录
- p := path.Join(m.Config(nfs.PATH), name)
+ p := path.Join(ice.USR_LOCAL_WORK, name)
+ if pid := m.Cmdx(nfs.CAT, path.Join(p, ice.Info.PidPath)); pid != "" && kit.FileExists("/proc/"+pid) {
+ m.Info("already exists %v", pid)
+ return // 已经启动
+ } else if m.Cmd(SPACE, name).Length() > 0 {
+ return // 已经启动
+ }
+
if m.Option(nfs.REPOS) != "" { // 下载源码
m.Cmd("web.code.git.repos", mdb.CREATE, m.OptionSimple(nfs.REPOS), nfs.PATH, p)
} else { // 创建目录
- nfs.MkdirAll(m, p)
+ file.MkdirAll(p, ice.MOD_DIR)
}
- // 任务模板
+ // 目录文件
if m.Option(nfs.TEMPLATE) != "" {
for _, file := range []string{
ice.ETC_MISS_SH, ice.SRC_MAIN_SHY, ice.SRC_MAIN_GO,
@@ -53,7 +74,7 @@ func _dream_show(m *ice.Message, name string) {
if kit.FileExists(path.Join(p, file)) {
continue
}
- switch m.Cmdy(nfs.COPY, path.Join(p, file), path.Join(m.Config(nfs.PATH), m.Option(nfs.TEMPLATE), file)); file {
+ switch m.Cmdy(nfs.COPY, path.Join(p, file), path.Join(ice.USR_LOCAL_WORK, m.Option(nfs.TEMPLATE), file)); file {
case ice.GO_MOD:
kit.Rewrite(path.Join(p, file), func(line string) string {
return kit.Select(line, "module "+name, strings.HasPrefix(line, "module"))
@@ -61,37 +82,26 @@ func _dream_show(m *ice.Message, name string) {
}
}
}
-
- // 任务脚本
m.Cmd(nfs.DEFS, path.Join(p, ice.ETC_MISS_SH), m.Config("miss"))
- defer m.Cmdy(nfs.DIR, p)
- if pid := m.Cmdx(nfs.CAT, path.Join(p, m.Conf(gdb.SIGNAL, kit.Keym(nfs.PATH)))); pid != "" && kit.FileExists("/proc/"+pid) {
- m.Info("already exists %v", pid)
- return // 已经启动
- } else if m.Cmd(SPACE, name).Length() > 0 {
- return // 已经启动
- }
-
- defer m.ToastProcess()()
-
- m.Optionv(cli.CMD_DIR, p)
+ // 环境变量
+ m.Optionv(cli.CMD_DIR, kit.Path(p))
m.Optionv(cli.CMD_ENV, kit.Simple(
cli.CTX_OPS, "http://:"+m.Cmd(SERVE, ice.OptionFields("")).Append(tcp.PORT),
cli.PATH, cli.BinPath(kit.Path(p, ice.BIN)), cli.HOME, kit.Env(cli.HOME),
- cli.SHELL, kit.Env(cli.SHELL), cli.TERM, kit.Env(cli.TERM),
+ cli.TERM, kit.Env(cli.TERM), cli.SHELL, kit.Env(cli.SHELL),
cli.USER, ice.Info.UserName, m.Configv(cli.ENV),
))
m.Optionv(cli.CMD_OUTPUT, path.Join(p, ice.BIN_BOOT_LOG))
- // 启动任务
+ defer m.ToastProcess()()
bin := kit.Select(os.Args[0], cli.SystemFind(m, ice.ICE_BIN, kit.Path(path.Join(p, ice.BIN)), kit.Path(ice.BIN)))
m.Cmd(cli.DAEMON, bin, SPACE, tcp.DIAL, ice.DEV, ice.OPS, m.OptionSimple(mdb.NAME, RIVER))
m.Sleep3s()
m.Option(cli.CMD_ENV, "")
m.Option(cli.CMD_OUTPUT, "")
- m.Event(DREAM_CREATE, kit.SimpleKV("", m.Option(mdb.TYPE), name)...)
+ m.Event(DREAM_CREATE, m.OptionSimple(mdb.TYPE, mdb.NAME)...)
}
const (
@@ -102,8 +112,8 @@ const (
const DREAM = "dream"
func init() {
- Index.Merge(&ice.Context{Commands: ice.Commands{
- DREAM: {Name: "dream name path auto start", Help: "梦想家", Actions: ice.Actions{
+ Index.MergeCommands(ice.Commands{
+ DREAM: {Name: "dream name path auto start", Help: "梦想家", Actions: ice.MergeAction(ice.Actions{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
m.Config("miss", _dream_miss)
}},
@@ -129,10 +139,10 @@ func init() {
cli.STOP: {Name: "stop", Help: "停止", Hand: func(m *ice.Message, arg ...string) {
m.Cmd(SPACE, mdb.MODIFY, m.OptionSimple(mdb.NAME), mdb.STATUS, cli.STOP)
m.Cmd(SPACE, m.Option(mdb.NAME), ice.EXIT)
- m.ProcessRefresh("100ms")
+ m.ProcessRefresh30ms()
}},
DREAM_STOP: {Name: "dream.stop type name", Help: "停止", Hand: func(m *ice.Message, arg ...string) {
- if m.Cmd(SPACE, m.Option(mdb.NAME)).Append(mdb.STATUS) == cli.STOP {
+ if m.CmdAppend(SPACE, m.Option(mdb.NAME), mdb.STATUS) == cli.STOP {
m.Cmd(mdb.DELETE, m.Prefix(SPACE), "", mdb.HASH, m.OptionSimple(mdb.NAME))
} else {
m.Cmd(mdb.DELETE, m.Prefix(SPACE), "", mdb.HASH, m.OptionSimple(mdb.NAME))
@@ -140,42 +150,19 @@ func init() {
}
}},
nfs.TRASH: {Name: "trash", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
- m.Cmd(nfs.TRASH, mdb.CREATE, path.Join(m.Config(nfs.PATH), m.Option(mdb.NAME)))
+ m.Cmd(nfs.TRASH, mdb.CREATE, path.Join(ice.USR_LOCAL_WORK, m.Option(mdb.NAME)))
m.ProcessRefresh30ms()
}},
- }, Hand: func(m *ice.Message, arg ...string) {
- if start := 0; len(arg) == 0 {
- _dream_list(m).SetAppend(mdb.TEXT)
- m.Tables(func(value ice.Maps) {
- if value[cli.STATUS] != cli.START {
- m.Push(mdb.TEXT, "")
- return
- }
- start++
- text := []string{}
- for _, line := range kit.Split(m.Cmdx(SPACE, value[mdb.NAME], cli.SYSTEM, "git", "diff", "--shortstat"), ice.FS, ice.FS) {
- if list := kit.Split(line); strings.Contains(line, "file") {
- text = append(text, list[0]+" file")
- } else if strings.Contains(line, "ins") {
- text = append(text, list[0]+" +++")
- } else if strings.Contains(line, "dele") {
- text = append(text, list[0]+" ---")
- }
- }
- m.Push(mdb.TEXT, strings.Join(text, ", "))
- }).Sort("status,type,name").StatusTimeCount(cli.START, start)
- if !m.IsMobileUA() {
+ }, mdb.HashAction("miss", _dream_miss)), Hand: func(m *ice.Message, arg ...string) {
+ if len(arg) == 0 {
+ if _dream_list(m); !m.IsMobileUA() {
m.Display("/plugin/table.js?style=card")
}
return
}
-
- m.Option(nfs.DIR_ROOT, path.Join(m.Config(nfs.PATH), arg[0]))
- m.Cmdy(nfs.CAT, arg[1:])
+ m.Cmdy(nfs.CAT, arg[1:], kit.Dict(nfs.DIR_ROOT, path.Join(ice.USR_LOCAL_WORK, arg[0])))
}},
- }, Configs: ice.Configs{
- DREAM: {Name: DREAM, Help: "梦想家", Value: kit.Data(nfs.PATH, ice.USR_LOCAL_WORK, "miss", _dream_miss)},
- }})
+ })
}
var _dream_miss = `#! /bin/sh
diff --git a/base/web/render.go b/base/web/render.go
index 1462cede..8088e529 100644
--- a/base/web/render.go
+++ b/base/web/render.go
@@ -2,6 +2,7 @@ package web
import (
"fmt"
+ "io"
"net/http"
"path"
"strings"
@@ -9,13 +10,15 @@ import (
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/aaa"
+ "shylinux.com/x/icebergs/base/mdb"
+ "shylinux.com/x/icebergs/base/nfs"
"shylinux.com/x/icebergs/base/tcp"
kit "shylinux.com/x/toolkits"
)
const (
- STATUS = "status"
COOKIE = "cookie"
+ STATUS = "status"
)
func Render(msg *ice.Message, cmd string, args ...ice.Any) {
@@ -27,30 +30,34 @@ func Render(msg *ice.Message, cmd string, args ...ice.Any) {
case COOKIE: // value [name [path [expire]]]
RenderCookie(msg, arg[0], arg[1:]...)
+ case STATUS, ice.RENDER_STATUS: // [code [text]]
+ RenderStatus(msg, kit.Int(kit.Select("200", arg, 0)), kit.Select("", arg, 1))
+
+ case ice.RENDER_REDIRECT: // url [arg...]
+ RenderRedirect(msg, arg...)
+
case ice.RENDER_DOWNLOAD: // file [type [name]]
- if strings.HasPrefix(arg[0], "http") {
+ if strings.HasPrefix(arg[0], ice.HTTP) {
http.Redirect(msg.W, msg.R, arg[0], http.StatusSeeOther)
break
}
msg.W.Header().Set("Content-Disposition", fmt.Sprintf("filename=%s", kit.Select(path.Base(kit.Select(arg[0], msg.Option("filename"))), arg, 2)))
- if RenderType(msg.W, arg[0], kit.Select("", arg, 1)); !ice.Info.Dump(msg.W, arg[0], nil) {
+ RenderType(msg.W, arg[0], kit.Select("", arg, 1))
+ if _, e := nfs.DiskFile.StatFile(arg[0]); e == nil {
http.ServeFile(msg.W, msg.R, kit.Path(arg[0]))
+ } else if f, e := nfs.PackFile.OpenFile(arg[0]); e == nil {
+ defer f.Close()
+ io.Copy(msg.W, f)
}
- case ice.RENDER_REDIRECT: // url [arg...]
- RenderRedirect(msg, arg...)
-
case ice.RENDER_RESULT:
if len(arg) > 0 { // [str [arg...]]
msg.W.Write([]byte(kit.Format(arg[0], args[1:]...)))
} else {
- args = append(args, "length:", len(msg.Result()))
+ args = append(args, nfs.SIZE, len(msg.Result()))
msg.W.Write([]byte(msg.Result()))
}
- case STATUS, ice.RENDER_STATUS: // [code [text]]
- RenderStatus(msg, kit.Int(kit.Select("200", arg, 0)), kit.Select("", arg, 1))
-
case ice.RENDER_JSON:
msg.W.Header().Set("Content-Type", "application/json")
msg.W.Write([]byte(arg[0]))
@@ -73,26 +80,33 @@ func Render(msg *ice.Message, cmd string, args ...ice.Any) {
msg.Echo(kit.Format(cmd, args...))
}
msg.W.Header().Set(ContentType, ContentJSON)
- fmt.Fprint(msg.W, msg.FormatsMeta())
+ fmt.Fprint(msg.W, msg.FormatMeta())
+ }
+}
+func RenderType(w http.ResponseWriter, name, mime string) {
+ if mime != "" {
+ w.Header().Set(ContentType, mime)
+ return
+ }
+
+ switch kit.Ext(name) {
+ case nfs.CSS:
+ w.Header().Set(ContentType, "text/css; charset=utf-8")
+ case "pdf":
+ w.Header().Set(ContentType, "application/pdf")
}
}
func RenderHeader(msg *ice.Message, key, value string) {
msg.W.Header().Set(key, value)
}
-func RenderStatus(msg *ice.Message, code int, text string) {
- msg.W.WriteHeader(code)
- msg.W.Write([]byte(text))
-}
-func CookieName(url string) string {
- return ice.MSG_SESSID + "_" + kit.ReplaceAll(kit.ParseURLMap(url)[tcp.HOST], ".", "_", ":", "_")
-}
func RenderCookie(msg *ice.Message, value string, arg ...string) { // name path expire
- expire := time.Now().Add(kit.Duration(kit.Select(msg.Conf(aaa.SESS, kit.Keym(aaa.EXPIRE)), arg, 2)))
+ expire := time.Now().Add(kit.Duration(kit.Select(msg.Conf(aaa.SESS, kit.Keym(mdb.EXPIRE)), arg, 2)))
http.SetCookie(msg.W, &http.Cookie{Value: value,
Name: kit.Select(CookieName(msg.Option(ice.MSG_USERWEB)), arg, 0), Path: kit.Select(ice.PS, arg, 1), Expires: expire})
}
-func RenderRedirect(msg *ice.Message, arg ...string) {
- http.Redirect(msg.W, msg.R, kit.MergeURL(arg[0], arg[1:]), http.StatusTemporaryRedirect)
+func RenderStatus(msg *ice.Message, code int, text string) {
+ msg.W.WriteHeader(code)
+ msg.W.Write([]byte(text))
}
func RenderRefresh(msg *ice.Message, arg ...string) { // url text delay
msg.Render(ice.RENDER_VOID)
@@ -107,27 +121,18 @@ func RenderRefresh(msg *ice.Message, arg ...string) { // url text delay