1
0
mirror of https://shylinux.com/x/icebergs synced 2025-06-26 18:37:29 +08:00
This commit is contained in:
IT 老营长 @云轩领航-创始人 2023-03-23 21:31:12 +08:00
parent fda4e3b889
commit f0fd9ed204
31 changed files with 343 additions and 518 deletions

View File

@ -1,12 +1,19 @@
package aaa package aaa
import ice "shylinux.com/x/icebergs" import (
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/mdb"
)
const ( const (
RSA = "rsa" RSA = "rsa"
) )
const AAA = "aaa" const AAA = "aaa"
var Index = &ice.Context{Name: AAA, Help: "认证模块"} var Index = &ice.Context{Name: AAA, Help: "认证模块", Commands: ice.Commands{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
ice.Info.Load(m).Cmd(ROLE, mdb.CREATE, TECH, VOID)
}},
}}
func init() { ice.Index.Register(Index, nil, ROLE, SESS, TOTP, USER, OFFER, EMAIL, RSA) } func init() { ice.Index.Register(Index, nil, OFFER, EMAIL, USER, TOTP, SESS, ROLE, RSA) }

View File

@ -10,6 +10,8 @@ import (
const ( const (
SEND = "send" SEND = "send"
SUBJECT = "subject"
CONTENT = "content"
) )
const EMAIL = "email" const EMAIL = "email"
@ -17,8 +19,6 @@ func init() {
const ( const (
TO = "to" TO = "to"
ADMIN = "admin" ADMIN = "admin"
SUBJECT = "subject"
CONTENT = "content"
SERVICE = "service" SERVICE = "service"
NL = "\r\n" NL = "\r\n"
DF = ": " DF = ": "
@ -26,16 +26,14 @@ func init() {
Index.MergeCommands(ice.Commands{ Index.MergeCommands(ice.Commands{
EMAIL: {Name: "email name auto create", Help: "邮件", Actions: ice.MergeActions(ice.Actions{ EMAIL: {Name: "email name auto create", Help: "邮件", Actions: ice.MergeActions(ice.Actions{
SEND: {Name: "send to*='shylinux@163.com' subject*=hi content*:textarea=hello", Help: "发送", Hand: func(m *ice.Message, arg ...string) { SEND: {Name: "send to*='shylinux@163.com' subject*=hi content*:textarea=hello", Help: "发送", Hand: func(m *ice.Message, arg ...string) {
if m.Option(SERVICE) == "" { kit.If(m.Option(SERVICE) == "", func() { m.Options(m.Cmd("", ADMIN).AppendSimple(SERVICE, USERNAME, PASSWORD)) })
m.Options(m.Cmd("", ADMIN).AppendSimple(SERVICE, USERNAME, PASSWORD))
}
if m.Warn(m.Option(SERVICE) == "", ice.ErrNotValid, SERVICE) { if m.Warn(m.Option(SERVICE) == "", ice.ErrNotValid, SERVICE) {
return return
} }
content := []byte(kit.JoinKV(DF, NL, "From", m.Option(USERNAME), "To", m.Option(TO), "Subject", m.Option(SUBJECT), "Content-Type", "text/html; charset=UTF-8") + NL + NL + m.Option(CONTENT)) content := []byte(kit.JoinKV(DF, NL, "From", m.Option(USERNAME), "To", m.Option(TO), "Subject", m.Option(SUBJECT), "Content-Type", "text/html; charset=UTF-8") + NL + NL + m.Option(CONTENT))
auth := smtp.PlainAuth("", m.Option(USERNAME), m.Option(PASSWORD), kit.Split(m.Option(SERVICE), ice.DF)[0]) auth := smtp.PlainAuth("", m.Option(USERNAME), m.Option(PASSWORD), kit.Split(m.Option(SERVICE), ice.DF)[0])
m.Warn(smtp.SendMail(m.Option(SERVICE), auth, m.Option(USERNAME), kit.Split(m.Option(TO)), content)) m.Warn(smtp.SendMail(m.Option(SERVICE), auth, m.Option(USERNAME), kit.Split(m.Option(TO)), content))
m.Logs(mdb.EXPORT, EMAIL, string(content)) m.Logs(EMAIL, SEND, string(content))
}}, }},
}, mdb.HashAction(mdb.SHORT, mdb.NAME, mdb.FIELD, "time,name,service,username,password", ice.ACTION, SEND))}, }, mdb.HashAction(mdb.SHORT, mdb.NAME, mdb.FIELD, "time,name,service,username,password", ice.ACTION, SEND))},
}) })

View File

@ -2,6 +2,7 @@ package aaa
import ( import (
ice "shylinux.com/x/icebergs" ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/gdb"
"shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/mdb"
kit "shylinux.com/x/toolkits" kit "shylinux.com/x/toolkits"
) )
@ -15,30 +16,26 @@ const OFFER = "offer"
func init() { func init() {
Index.MergeCommands(ice.Commands{ Index.MergeCommands(ice.Commands{
OFFER: {Name: "offer hash auto", Help: "邀请", Actions: ice.MergeActions(ice.Actions{ OFFER: {Name: "offer hash auto", Help: "邀请", Actions: ice.MergeActions(ice.Actions{
INVITE: {Name: "invite email*='shylinux@163.com' content", Help: "邀请", Hand: func(m *ice.Message, arg ...string) { INVITE: {Name: "invite email*='shylinux@163.com' subject content", Help: "邀请", Hand: func(m *ice.Message, arg ...string) {
h := mdb.HashCreate(m.Spawn(), m.OptionSimple(EMAIL, "content"), "from", m.Option(ice.MSG_USERNAME), mdb.STATUS, INVITE) h := mdb.HashCreate(m.Spawn(), m.OptionSimple(EMAIL, SUBJECT, CONTENT), "from", m.Option(ice.MSG_USERNAME), mdb.STATUS, INVITE)
msg := m.Cmd("web.share", mdb.CREATE, mdb.TYPE, "field", mdb.NAME, m.PrefixKey(), mdb.TEXT, kit.Format(kit.List(h)), m.Cmd(EMAIL, SEND, m.Option(EMAIL), m.OptionDefault(SUBJECT, "welcome to contents, please continue"),
kit.Dict(ice.MSG_USERNAME, m.Option(EMAIL), ice.MSG_USERNICK, VOID, ice.MSG_USERROLE, VOID)) m.OptionDefault(CONTENT, ice.Render(m, ice.RENDER_ANCHOR, m.Cmdx("host", "publish", m.MergePodCmd("", "", mdb.HASH, h, gdb.DEBUG, ice.TRUE)))),
m.Cmd(EMAIL, SEND, m.Option(EMAIL), "welcome to contents, please continue", ice.Render(m, ice.RENDER_ANCHOR, kit.MergeURL(msg.Option(mdb.LINK), "debug", "true"))) )
}}, }},
ACCEPT: {Help: "接受", Hand: func(m *ice.Message, arg ...string) { ACCEPT: {Help: "接受", Hand: func(m *ice.Message, arg ...string) {
if m.Warn(m.Option(mdb.HASH) == "", ice.ErrNotValid, mdb.HASH) { if m.Warn(m.Option(mdb.HASH) == "", ice.ErrNotValid, mdb.HASH) {
return return
} }
msg := m.Cmd("", m.Option(mdb.HASH)) msg := m.Cmd("", m.Option(mdb.HASH))
ls := kit.Split(msg.Option(EMAIL), ice.AT) if ls := kit.Split(msg.Append(EMAIL), ice.AT); !m.Warn(msg.Length() == 0 || len(ls) < 2, ice.ErrNotValid, m.Option(mdb.HASH)) {
m.Cmd(USER, mdb.CREATE, USERNAME, msg.Option(EMAIL), USERNICK, ls[0], USERZONE, ls[1]) m.Cmd(USER, mdb.CREATE, USERNICK, ls[0], USERNAME, msg.Append(EMAIL), USERZONE, ls[1])
m.ProcessOpen(kit.MergeURL2(m.Option(ice.MSG_USERWEB), ice.PS, ice.MSG_SESSID, SessCreate(m, msg.Option(EMAIL)))) m.ProcessOpen(kit.MergeURL2(m.Option(ice.MSG_USERWEB), ice.PS, ice.MSG_SESSID, SessCreate(m, msg.Append(EMAIL)), mdb.HASH, "", gdb.DEBUG, ice.TRUE))
mdb.HashModify(m, m.OptionSimple(mdb.HASH), mdb.STATUS, ACCEPT) mdb.HashModify(m, m.OptionSimple(mdb.HASH), mdb.STATUS, ACCEPT)
}},
}, mdb.HashAction(mdb.SHORT, mdb.UNIQ, mdb.FIELD, "time,hash,status,from,email,content"), RoleAction(ACCEPT)), Hand: func(m *ice.Message, arg ...string) {
if len(arg) == 0 && m.Option(ice.MSG_USERROLE) == VOID {
return
} }
if mdb.HashSelect(m, arg...); len(arg) == 0 { }},
m.Action(INVITE) }, mdb.HashAction(mdb.SHORT, mdb.UNIQ, mdb.FIELD, "time,hash,status,from,email,title,content"), RoleAction(ACCEPT)), Hand: func(m *ice.Message, arg ...string) {
} else { if !m.Warn(len(arg) == 0 && m.Option(ice.MSG_USERROLE) == VOID, ice.ErrNotRight) {
m.PushAction(ACCEPT) kit.If(mdb.HashSelect(m, arg...).FieldsIsDetail(), func() { m.PushAction(ACCEPT) }, func() { m.Action(INVITE) })
} }
}}, }},
}) })

View File

@ -11,7 +11,12 @@ import (
) )
func _role_keys(key ...string) string { func _role_keys(key ...string) string {
return strings.TrimPrefix(strings.TrimSuffix(strings.Replace(path.Join(strings.Replace(kit.Keys(key), ice.PT, ice.PS, -1)), ice.PS, ice.PT, -1), ice.PT), ice.PT) if _key := kit.Slice(strings.Split(key[0], ice.PT), -1)[0]; _key != "" {
if c, ok := ice.Info.Index[_key].(*ice.Context); ok && kit.Keys(c.Prefix(), _key) == key[0] {
key[0] = _key
}
}
return strings.TrimPrefix(strings.TrimPrefix(strings.TrimSuffix(strings.Replace(path.Join(strings.Replace(kit.Keys(key), ice.PT, ice.PS, -1)), ice.PS, ice.PT, -1), ice.PT), ice.PT), "web.")
} }
func _role_set(m *ice.Message, role, zone, key string, status bool) { func _role_set(m *ice.Message, role, zone, key string, status bool) {
m.Logs(mdb.INSERT, mdb.KEY, ROLE, ROLE, role, zone, key) m.Logs(mdb.INSERT, mdb.KEY, ROLE, ROLE, role, zone, key)
@ -22,33 +27,21 @@ func _role_black(m *ice.Message, role, key string) { _role_set(m, role, BLACK, k
func _role_check(value ice.Map, key []string, ok bool) bool { func _role_check(value ice.Map, key []string, ok bool) bool {
white, black := value[WHITE].(ice.Map), value[BLACK].(ice.Map) white, black := value[WHITE].(ice.Map), value[BLACK].(ice.Map)
for i := 0; i < len(key); i++ { for i := 0; i < len(key); i++ {
if v, o := white[kit.Join(key[:i+1], ice.PT)]; o && v == true { kit.If(white[kit.Join(key[:i+1], ice.PT)], func() { ok = true })
ok = true kit.If(black[kit.Join(key[:i+1], ice.PT)], func() { ok = false })
}
if v, o := black[kit.Join(key[:i+1], ice.PT)]; o && v == true {
ok = false
}
} }
return ok return ok
} }
func _role_right(m *ice.Message, role string, key ...string) (ok bool) { func _role_right(m *ice.Message, role string, key ...string) (ok bool) {
if role == ROOT { return role == ROOT || len(mdb.HashSelectDetails(m, kit.Select(VOID, role), func(value ice.Map) bool { return _role_check(value, key, role == TECH) })) > 0
return true
}
mdb.HashSelectDetail(m, kit.Select(VOID, role), func(value ice.Map) {
ok = _role_check(value, key, role == TECH)
})
return
} }
func _role_list(m *ice.Message, role string) *ice.Message { func _role_list(m *ice.Message, role string) *ice.Message {
mdb.HashSelectDetail(m, kit.Select(VOID, role), func(value ice.Map) { mdb.HashSelectDetail(m, kit.Select(VOID, role), func(value ice.Map) {
kit.For(value[WHITE], func(k string, v ice.Any) { kit.For(value[WHITE], func(k string, v ice.Any) {
m.Push(ROLE, kit.Value(value, mdb.NAME)) m.Push(ROLE, kit.Value(value, mdb.NAME)).Push(mdb.ZONE, WHITE).Push(mdb.KEY, k).Push(mdb.STATUS, v)
m.Push(mdb.ZONE, WHITE).Push(mdb.KEY, k).Push(mdb.STATUS, v)
}) })
kit.For(value[BLACK], func(k string, v ice.Any) { kit.For(value[BLACK], func(k string, v ice.Any) {
m.Push(ROLE, kit.Value(value, mdb.NAME)) m.Push(ROLE, kit.Value(value, mdb.NAME)).Push(mdb.ZONE, BLACK).Push(mdb.KEY, k).Push(mdb.STATUS, v)
m.Push(mdb.ZONE, BLACK).Push(mdb.KEY, k).Push(mdb.STATUS, v)
}) })
}) })
return m.Sort(mdb.KEY).StatusTimeCount() return m.Sort(mdb.KEY).StatusTimeCount()
@ -69,7 +62,6 @@ const ROLE = "role"
func init() { func init() {
Index.MergeCommands(ice.Commands{ Index.MergeCommands(ice.Commands{
ROLE: {Name: "role role auto insert", Help: "角色", Actions: ice.MergeActions(ice.Actions{ ROLE: {Name: "role role auto insert", Help: "角色", Actions: ice.MergeActions(ice.Actions{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { m.Cmd("", mdb.CREATE, TECH, VOID) }},
mdb.CREATE: {Hand: func(m *ice.Message, arg ...string) { mdb.CREATE: {Hand: func(m *ice.Message, arg ...string) {
kit.For(arg, func(role string) { kit.For(arg, func(role string) {
mdb.Rich(m, ROLE, nil, kit.Dict(mdb.NAME, role, BLACK, kit.Dict(), WHITE, kit.Dict())) mdb.Rich(m, ROLE, nil, kit.Dict(mdb.NAME, role, BLACK, kit.Dict(), WHITE, kit.Dict()))
@ -91,18 +83,15 @@ func init() {
}}, }},
}) })
} }
func RoleAction(key ...string) ice.Actions { func RoleAction(key ...string) ice.Actions {
return ice.Actions{ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { return ice.Actions{ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
cmd := m.PrefixKey()
if c, ok := ice.Info.Index[m.CommandKey()].(*ice.Context); ok && c == m.Target() { if c, ok := ice.Info.Index[m.CommandKey()].(*ice.Context); ok && c == m.Target() {
m.Cmd(ROLE, WHITE, VOID, m.CommandKey()) cmd = m.CommandKey()
m.Cmd(ROLE, BLACK, VOID, m.CommandKey(), ice.ACTION)
} }
m.Cmd(ROLE, WHITE, VOID, m.PrefixKey()) m.Cmd(ROLE, WHITE, VOID, cmd)
m.Cmd(ROLE, BLACK, VOID, m.PrefixKey(), ice.ACTION) m.Cmd(ROLE, BLACK, VOID, cmd, ice.ACTION)
m.Cmd(ROLE, WHITE, VOID, strings.TrimPrefix(m.PrefixKey(), "web.")) kit.For(key, func(key string) { m.Cmd(ROLE, WHITE, VOID, cmd, ice.ACTION, key) })
m.Cmd(ROLE, BLACK, VOID, strings.TrimPrefix(m.PrefixKey(), "web."), ice.ACTION)
kit.For(key, func(key string) { m.Cmd(ROLE, WHITE, VOID, m.PrefixKey(), ice.ACTION, key) })
}}} }}}
} }
func WhiteAction(key ...string) ice.Actions { func WhiteAction(key ...string) ice.Actions {
@ -112,15 +101,6 @@ func WhiteAction(key ...string) ice.Actions {
kit.For(key, func(key string) { m.Cmd(ROLE, WHITE, VOID, m.CommandKey(), ice.ACTION, key) }) kit.For(key, func(key string) { m.Cmd(ROLE, WHITE, VOID, m.CommandKey(), ice.ACTION, key) })
}}} }}}
} }
func BlackAction(key ...string) ice.Actions {
return ice.Actions{ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
m.Cmd(ROLE, WHITE, VOID, m.CommandKey())
kit.For(key, func(key string) { m.Cmd(ROLE, BLACK, VOID, m.CommandKey(), ice.ACTION, key) })
}}}
}
func RoleRight(m *ice.Message, role string, key ...string) bool {
return m.Cmdx(ROLE, RIGHT, role, key) == ice.OK
}
func Right(m *ice.Message, key ...ice.Any) bool { func Right(m *ice.Message, key ...ice.Any) bool {
return m.Option(ice.MSG_USERROLE) == ROOT || !m.Warn(m.Cmdx(ROLE, RIGHT, m.Option(ice.MSG_USERROLE), key, logs.FileLineMeta(-1)) != ice.OK, return m.Option(ice.MSG_USERROLE) == ROOT || !m.Warn(m.Cmdx(ROLE, RIGHT, m.Option(ice.MSG_USERROLE), key, logs.FileLineMeta(-1)) != ice.OK,
ice.ErrNotRight, kit.Keys(key...), USERROLE, m.Option(ice.MSG_USERROLE), logs.FileLineMeta(-1)) ice.ErrNotRight, kit.Keys(key...), USERROLE, m.Option(ice.MSG_USERROLE), logs.FileLineMeta(-1))

View File

@ -2,20 +2,17 @@ package aaa
import ( import (
ice "shylinux.com/x/icebergs" ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/gdb"
"shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/mdb"
kit "shylinux.com/x/toolkits" kit "shylinux.com/x/toolkits"
"shylinux.com/x/toolkits/logs" "shylinux.com/x/toolkits/logs"
) )
func _sess_create(m *ice.Message, username string, arg ...string) (h string) { func _sess_create(m *ice.Message, username string, arg ...string) {
if msg := m.Cmd(USER, username); msg.Length() > 0 { if msg := m.Cmd(USER, username); msg.Length() > 0 {
h = mdb.HashCreate(m, msg.AppendSimple(USERNICK, USERNAME, USERROLE), arg) mdb.HashCreate(m, msg.AppendSimple(USERNICK, USERNAME, USERROLE), arg)
} else { } else {
h = mdb.HashCreate(m, m.OptionSimple(USERNICK, USERNAME, USERROLE), arg) mdb.HashCreate(m, m.OptionSimple(USERNICK, USERNAME, USERROLE), arg)
} }
gdb.Event(m, SESS_CREATE, SESS, h, USERNAME, username)
return
} }
func _sess_check(m *ice.Message, sessid string) { func _sess_check(m *ice.Message, sessid string) {
if val := mdb.HashSelectDetails(m, sessid, func(value ice.Map) bool { return !m.WarnTimeNotValid(value[mdb.TIME], sessid) }); len(val) > 0 { if val := mdb.HashSelectDetails(m, sessid, func(value ice.Map) bool { return !m.WarnTimeNotValid(value[mdb.TIME], sessid) }); len(val) > 0 {
@ -29,13 +26,8 @@ const (
) )
const ( const (
CHECK = "check" CHECK = "check"
GRANT = "grant"
LOGIN = "login" LOGIN = "login"
LOGOUT = "logout" LOGOUT = "logout"
SESSID = "sessid"
)
const (
SESS_CREATE = "sess.create"
) )
const SESS = "sess" const SESS = "sess"
@ -45,10 +37,8 @@ func init() {
mdb.CREATE: {Name: "create username*", Hand: func(m *ice.Message, arg ...string) { mdb.CREATE: {Name: "create username*", Hand: func(m *ice.Message, arg ...string) {
_sess_create(m, m.Option(USERNAME), UA, m.Option(ice.MSG_USERUA), IP, m.Option(ice.MSG_USERIP)) _sess_create(m, m.Option(USERNAME), UA, m.Option(ice.MSG_USERUA), IP, m.Option(ice.MSG_USERIP))
}}, }},
CHECK: {Name: "check sessid*", Hand: func(m *ice.Message, arg ...string) { CHECK: {Name: "check sessid*", Hand: func(m *ice.Message, arg ...string) { _sess_check(m, m.Option(ice.MSG_SESSID)) }},
_sess_check(m, m.Option(SESSID)) }, mdb.HashAction(mdb.EXPIRE, mdb.MONTH, mdb.SHORT, mdb.UNIQ, mdb.FIELD, "time,hash,usernick,username,userrole,ua,ip"), mdb.ImportantDataAction())},
}},
}, mdb.HashAction(mdb.SHORT, mdb.UNIQ, mdb.FIELD, "time,hash,username,usernick,userrole,ua,ip", mdb.EXPIRE, mdb.MONTH, mdb.ImportantDataAction()))},
}) })
} }
@ -68,8 +58,5 @@ func SessAuth(m *ice.Message, value ice.Any, arg ...string) *ice.Message {
) )
} }
func SessLogout(m *ice.Message, arg ...string) { func SessLogout(m *ice.Message, arg ...string) {
if m.Option(ice.MSG_SESSID) == "" { kit.If(m.Option(ice.MSG_SESSID) != "", func() { m.Cmd(SESS, mdb.REMOVE, mdb.HASH, m.Option(ice.MSG_SESSID)) })
return
}
m.Cmd(SESS, mdb.REMOVE, kit.Dict(mdb.HASH, m.Option(ice.MSG_SESSID)))
} }

View File

@ -23,12 +23,8 @@ func _totp_gen(per int64) string {
} }
func _totp_get(key string, per int64, num int) string { func _totp_get(key string, per int64, num int) string {
buf, now := []byte{}, kit.Int64(time.Now().Unix()/per) buf, now := []byte{}, kit.Int64(time.Now().Unix()/per)
for i := 0; i < 8; i++ { kit.For(8, func(i int) { buf = append(buf, byte((uint64(now) >> uint64(((7 - i) * 8))))) })
buf = append(buf, byte((uint64(now) >> uint64(((7 - i) * 8))))) kit.If(len(key)%8, func(l int) { key += strings.Repeat(ice.EQ, 8-l) })
}
if l := len(key) % 8; l != 0 {
key += strings.Repeat(ice.EQ, 8-l)
}
s, _ := base32.StdEncoding.DecodeString(strings.ToUpper(key)) s, _ := base32.StdEncoding.DecodeString(strings.ToUpper(key))
hm := hmac.New(sha1.New, s) hm := hmac.New(sha1.New, s)
hm.Write(buf) hm.Write(buf)

View File

@ -1,21 +1,35 @@
package gdb package gdb
import ( import (
"fmt"
"os" "os"
"os/signal"
"syscall"
"time" "time"
ice "shylinux.com/x/icebergs" ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/mdb"
kit "shylinux.com/x/toolkits" kit "shylinux.com/x/toolkits"
"shylinux.com/x/toolkits/logs"
) )
type Frame struct{ s chan os.Signal } type Frame struct{ s chan os.Signal }
func (f *Frame) Begin(m *ice.Message, arg ...string) ice.Server { func (f *Frame) listen(m *ice.Message, s int, arg ...string) {
f.s = make(chan os.Signal, 3) signal.Notify(f.s, syscall.Signal(s))
return f mdb.HashCreate(m, SIGNAL, s, arg)
} }
func (f *Frame) Start(m *ice.Message, arg ...string) bool { func (f *Frame) Begin(m *ice.Message, arg ...string) {
f.s = make(chan os.Signal, 10)
}
func (f *Frame) Start(m *ice.Message, arg ...string) {
kit.If(ice.Info.PidPath, func(p string) {
if f, p, e := logs.CreateFile(p); e == nil {
defer f.Close()
fmt.Fprint(f, os.Getpid())
m.Logs("save", PID, p)
}
})
t := kit.Duration(mdb.Conf(m, TIMER, kit.Keym(TICK))) t := kit.Duration(mdb.Conf(m, TIMER, kit.Keym(TICK)))
enable := mdb.Conf(m, TIMER, kit.Keym("enable")) == ice.TRUE enable := mdb.Conf(m, TIMER, kit.Keym("enable")) == ice.TRUE
for { for {
@ -26,20 +40,13 @@ func (f *Frame) Start(m *ice.Message, arg ...string) bool {
} }
case s, ok := <-f.s: case s, ok := <-f.s:
if !ok { if !ok {
return true return
} }
m.Cmd(SIGNAL, HAPPEN, SIGNAL, s) m.Cmd(SIGNAL, HAPPEN, SIGNAL, s)
} }
} }
return true
}
func (f *Frame) Close(m *ice.Message, arg ...string) bool {
close(f.s)
return true
}
func (f *Frame) Spawn(m *ice.Message, c *ice.Context, arg ...string) ice.Server {
return &Frame{}
} }
func (f *Frame) Close(m *ice.Message, arg ...string) { close(f.s) }
const GDB = "gdb" const GDB = "gdb"

View File

@ -1,7 +1,6 @@
package gdb package gdb
import ( import (
"fmt"
"os" "os"
"os/signal" "os/signal"
"runtime" "runtime"
@ -11,13 +10,11 @@ import (
"shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/mdb"
kit "shylinux.com/x/toolkits" kit "shylinux.com/x/toolkits"
"shylinux.com/x/toolkits/file" "shylinux.com/x/toolkits/file"
"shylinux.com/x/toolkits/logs"
) )
func _signal_listen(m *ice.Message, s int, arg ...string) { func _signal_listen(m *ice.Message, s int, arg ...string) {
if f, ok := m.Target().Server().(*Frame); ok { if f, ok := m.Target().Server().(*Frame); ok {
signal.Notify(f.s, syscall.Signal(s)) f.listen(m, s, arg...)
mdb.HashCreate(m, SIGNAL, s, arg)
} }
} }
func _signal_action(m *ice.Message, arg ...string) { func _signal_action(m *ice.Message, arg ...string) {
@ -58,14 +55,6 @@ func init() {
} }
_signal_listen(m, 2, mdb.NAME, "重启", ice.CMD, "exit 1") _signal_listen(m, 2, mdb.NAME, "重启", ice.CMD, "exit 1")
_signal_listen(m, 3, mdb.NAME, "退出", ice.CMD, "exit 0") _signal_listen(m, 3, mdb.NAME, "退出", ice.CMD, "exit 0")
if ice.Info.PidPath == "" {
return
}
if f, p, e := logs.CreateFile(ice.Info.PidPath); e == nil {
defer f.Close()
fmt.Fprint(f, os.Getpid())
m.Logs("save", PID, p)
}
}}, }},
LISTEN: {Name: "listen signal name cmd", Help: "监听", Hand: func(m *ice.Message, arg ...string) { LISTEN: {Name: "listen signal name cmd", Help: "监听", Hand: func(m *ice.Message, arg ...string) {
_signal_listen(m, kit.Int(m.Option(SIGNAL)), arg...) _signal_listen(m, kit.Int(m.Option(SIGNAL)), arg...)

View File

@ -2,6 +2,7 @@ package log
import ( import (
"bufio" "bufio"
"fmt"
"path" "path"
ice "shylinux.com/x/icebergs" ice "shylinux.com/x/icebergs"
@ -12,7 +13,6 @@ import (
) )
type Log struct { type Log struct {
m *ice.Message
p string p string
l string l string
s string s string
@ -20,56 +20,47 @@ type Log struct {
type Frame struct{ p chan *Log } type Frame struct{ p chan *Log }
func (f *Frame) Begin(m *ice.Message, arg ...string) ice.Server { func (f *Frame) Begin(m *ice.Message, arg ...string) {
f.p = make(chan *Log, ice.MOD_BUFS) f.p = make(chan *Log, ice.MOD_BUFS)
ice.Info.Log = func(m *ice.Message, p, l, s string) { f.p <- &Log{m: m, p: p, l: l, s: s} } ice.Info.Log = func(m *ice.Message, p, l, s string) { f.p <- &Log{p: p, l: l, s: s} }
return f
} }
func (f *Frame) Start(m *ice.Message, arg ...string) bool { func (f *Frame) Start(m *ice.Message, arg ...string) {
m.Option("_lock", m.PrefixKey()) m.Option("_lock", m.PrefixKey())
mdb.Confm(m, FILE, nil, func(key string, value ice.Map) {
if f, p, e := logs.CreateFile(kit.Format(value[nfs.PATH])); e == nil {
value[FILE] = bufio.NewWriter(f)
m.Logs(nfs.SAVE, nfs.FILE, p)
}
})
for { for {
select { select {
case l, ok := <-f.p: case l, ok := <-f.p:
if !ok { if !ok {
return true return
} }
for _, file := range []string{m.Conf(SHOW, kit.Keys(l.l, FILE)), BENCH} { kit.For([]string{m.Conf(SHOW, kit.Keys(l.l, FILE)), BENCH}, func(file string) {
if file == "" { if file == "" {
continue return
} }
view := mdb.Confm(m, VIEW, m.Conf(SHOW, kit.Keys(l.l, VIEW)))
bio := m.Confv(FILE, kit.Keys(file, FILE)).(*bufio.Writer) bio := m.Confv(FILE, kit.Keys(file, FILE)).(*bufio.Writer)
if bio == nil { if bio == nil {
continue return
} }
bio.WriteString(l.p) defer bio.Flush()
bio.WriteString(ice.SP) defer fmt.Fprintln(bio)
if ice.Info.Colors == true { fmt.Fprint(bio, l.p, ice.SP)
if p, ok := view[PREFIX].(string); ok { view := mdb.Confm(m, VIEW, m.Conf(SHOW, kit.Keys(l.l, VIEW)))
bio.WriteString(p) kit.If(ice.Info.Colors, func() { bio.WriteString(kit.Format(view[PREFIX])) })
defer kit.If(ice.Info.Colors, func() { bio.WriteString(kit.Format(view[SUFFIX])) })
fmt.Fprint(bio, l.l, ice.SP, l.s)
})
} }
} }
bio.WriteString(l.l)
bio.WriteString(ice.SP)
bio.WriteString(l.s)
if ice.Info.Colors == true {
if p, ok := view[SUFFIX].(string); ok {
bio.WriteString(p)
}
}
bio.WriteString(ice.NL)
bio.Flush()
}
}
}
return true
} }
func (f *Frame) Close(m *ice.Message, arg ...string) bool { func (f *Frame) Close(m *ice.Message, arg ...string) {
ice.Info.Log = nil ice.Info.Log = nil
close(f.p) close(f.p)
return true
} }
func (f *Frame) Spawn(m *ice.Message, c *ice.Context, arg ...string) ice.Server { return &Frame{} }
const ( const (
PREFIX = "prefix" PREFIX = "prefix"
@ -107,11 +98,6 @@ var Index = &ice.Context{Name: LOG, Help: "日志模块", Configs: ice.Configs{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
mdb.Confm(m, FILE, nil, func(key string, value ice.Map) { mdb.Confm(m, FILE, nil, func(key string, value ice.Map) {
kit.For(value[mdb.LIST], func(index int, k string) { m.Conf(SHOW, kit.Keys(k, FILE), key) }) kit.For(value[mdb.LIST], func(index int, k string) { m.Conf(SHOW, kit.Keys(k, FILE), key) })
if f, p, e := logs.CreateFile(kit.Format(value[nfs.PATH])); e == nil {
m.Cap(ice.CTX_STREAM, path.Base(p))
value[FILE] = bufio.NewWriter(f)
m.Logs(nfs.SAVE, nfs.FILE, p)
}
}) })
mdb.Confm(m, VIEW, nil, func(key string, value ice.Map) { mdb.Confm(m, VIEW, nil, func(key string, value ice.Map) {
kit.For(value[mdb.LIST], func(index int, k string) { m.Conf(SHOW, kit.Keys(k, VIEW), key) }) kit.For(value[mdb.LIST], func(index int, k string) { m.Conf(SHOW, kit.Keys(k, VIEW), key) })

View File

@ -125,8 +125,9 @@ const HASH = "hash"
func HashAction(arg ...Any) ice.Actions { func HashAction(arg ...Any) ice.Actions {
return ice.Actions{ice.CTX_INIT: AutoConfig(append(kit.List(FIELD, HASH_FIELD), arg...)...), return ice.Actions{ice.CTX_INIT: AutoConfig(append(kit.List(FIELD, HASH_FIELD), arg...)...),
ice.CTX_EXIT: {Hand: func(m *ice.Message, arg ...string) { HashSelectClose(m) }}, ice.CTX_EXIT: {Hand: func(m *ice.Message, arg ...string) {
HashSelectClose(m)
}},
INPUTS: {Hand: func(m *ice.Message, arg ...string) { HashInputs(m, arg) }}, INPUTS: {Hand: func(m *ice.Message, arg ...string) { HashInputs(m, arg) }},
CREATE: {Hand: func(m *ice.Message, arg ...string) { HashCreate(m, arg) }}, CREATE: {Hand: func(m *ice.Message, arg ...string) { HashCreate(m, arg) }},
REMOVE: {Hand: func(m *ice.Message, arg ...string) { HashRemove(m, arg) }}, REMOVE: {Hand: func(m *ice.Message, arg ...string) { HashRemove(m, arg) }},
@ -269,7 +270,7 @@ func HashSelectTarget(m *ice.Message, key string, create Any) (target Any) {
func HashSelectClose(m *ice.Message) *ice.Message { func HashSelectClose(m *ice.Message) *ice.Message {
HashSelectValue(m, func(value Map) { HashSelectValue(m, func(value Map) {
if c, ok := value[TARGET].(io.Closer); ok { if c, ok := value[TARGET].(io.Closer); ok {
c.Close() m.Warn(c.Close())
} }
delete(value, TARGET) delete(value, TARGET)
}) })

View File

@ -33,21 +33,11 @@ type Frame struct {
} }
func (f *Frame) prompt(m *ice.Message, list ...string) *Frame { func (f *Frame) prompt(m *ice.Message, list ...string) *Frame {
if f.source != STDIO { if f.source != STDIO || m.Target().Cap(ice.CTX_STATUS) == ice.CTX_CLOSE {
return f return f
} }
if m.Target().Cap(ice.CTX_STATUS) == ice.CTX_CLOSE { kit.If(len(list) == 0, func() { list = append(list, f.ps1...) })
return f fmt.Fprintf(f.stdout, kit.Select("\r", "\r\033[2K", ice.Info.Colors))
}
if len(list) == 0 {
list = append(list, f.ps1...)
}
if ice.Info.Colors {
fmt.Fprintf(f.stdout, "\r\033[2K")
} else {
fmt.Fprintf(f.stdout, "\r")
}
for _, v := range list { for _, v := range list {
switch v { switch v {
case mdb.COUNT: case mdb.COUNT:
@ -59,9 +49,7 @@ func (f *Frame) prompt(m *ice.Message, list ...string) *Frame {
case TARGET: case TARGET:
fmt.Fprintf(f.stdout, f.target.Name) fmt.Fprintf(f.stdout, f.target.Name)
default: default:
if ice.Info.Colors || v[0] != '\033' { kit.If(ice.Info.Colors || v[0] != '\033', func() { fmt.Fprintf(f.stdout, v) })
fmt.Fprintf(f.stdout, v)
}
} }
} }
return f return f
@ -122,6 +110,9 @@ func (f *Frame) scan(m *ice.Message, h, line string) *Frame {
f.ps2 = kit.Simple(mdb.Confv(m, PROMPT, kit.Keym(PS2))) f.ps2 = kit.Simple(mdb.Confv(m, PROMPT, kit.Keym(PS2)))
// m.Options(MESSAGE, m, ice.LOG_DISABLE, ice.TRUE) // m.Options(MESSAGE, m, ice.LOG_DISABLE, ice.TRUE)
m.I, m.O = f.stdin, f.stdout m.I, m.O = f.stdin, f.stdout
if msg := m.Cmd("serve"); msg.Append("status") == "start" {
m.Cmd(PRINTF, kit.Dict(nfs.CONTENT, ice.NL+ice.Render(m, ice.RENDER_QRCODE, tcp.PublishLocalhost(m, kit.Format("http://localhost:%s", msg.Append(tcp.PORT))))))
}
ps, bio := f.ps1, bufio.NewScanner(f.stdin) ps, bio := f.ps1, bufio.NewScanner(f.stdin)
for f.prompt(m, ps...); f.stdin != nil && bio.Scan(); f.prompt(m, ps...) { for f.prompt(m, ps...); f.stdin != nil && bio.Scan(); f.prompt(m, ps...) {
if len(bio.Text()) == 0 && h == STDIO { if len(bio.Text()) == 0 && h == STDIO {
@ -152,16 +143,15 @@ func (f *Frame) scan(m *ice.Message, h, line string) *Frame {
return f return f
} }
func (f *Frame) Begin(m *ice.Message, arg ...string) ice.Server { func (f *Frame) Begin(m *ice.Message, arg ...string) {
switch strings.Split(os.Getenv(cli.TERM), "-")[0] { switch strings.Split(os.Getenv(cli.TERM), "-")[0] {
case "xterm", "screen": case "xterm", "screen":
ice.Info.Colors = true ice.Info.Colors = true
default: default:
ice.Info.Colors = false ice.Info.Colors = false
} }
return f
} }
func (f *Frame) Start(m *ice.Message, arg ...string) bool { func (f *Frame) Start(m *ice.Message, arg ...string) {
m.Optionv(FRAME, f) m.Optionv(FRAME, f)
switch f.source = kit.Select(STDIO, arg, 0); f.source { switch f.source = kit.Select(STDIO, arg, 0); f.source {
case STDIO: case STDIO:
@ -185,7 +175,7 @@ func (f *Frame) Start(m *ice.Message, arg ...string) bool {
m.Option(ice.MSG_SCRIPT, f.source) m.Option(ice.MSG_SCRIPT, f.source)
f.target = m.Source() f.target = m.Source()
if msg := m.Cmd(nfs.CAT, f.source); msg.IsErr() { if msg := m.Cmd(nfs.CAT, f.source); msg.IsErr() {
return true return
} else { } else {
buf := bytes.NewBuffer(make([]byte, 0, ice.MOD_BUFS)) buf := bytes.NewBuffer(make([]byte, 0, ice.MOD_BUFS))
f.stdin, f.stdout = bytes.NewBufferString(msg.Result()), buf f.stdin, f.stdout = bytes.NewBufferString(msg.Result()), buf
@ -193,14 +183,12 @@ func (f *Frame) Start(m *ice.Message, arg ...string) bool {
} }
f.scan(m, "", "") f.scan(m, "", "")
} }
return true
} }
func (f *Frame) Close(m *ice.Message, arg ...string) bool { func (f *Frame) Close(m *ice.Message, arg ...string) {
if stdin, ok := f.stdin.(io.Closer); ok { if stdin, ok := f.stdin.(io.Closer); ok {
stdin.Close() stdin.Close()
} }
f.stdin = nil f.stdin = nil
return true
} }
func (f *Frame) Spawn(m *ice.Message, c *ice.Context, arg ...string) ice.Server { func (f *Frame) Spawn(m *ice.Message, c *ice.Context, arg ...string) ice.Server {
return &Frame{} return &Frame{}

View File

@ -6,8 +6,16 @@ import (
ice "shylinux.com/x/icebergs" ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/mdb"
kit "shylinux.com/x/toolkits" kit "shylinux.com/x/toolkits"
"shylinux.com/x/toolkits/logs"
) )
func _broad_addr(m *ice.Message, host, port string) *net.UDPAddr {
if addr, e := net.ResolveUDPAddr("udp4", kit.Format("%s:%s", host, port)); !m.Warn(e, ice.ErrNotValid, host, port, logs.FileLineMeta(2)) {
return addr
}
return nil
}
type Listener struct { type Listener struct {
m *ice.Message m *ice.Message
h string h string
@ -26,7 +34,21 @@ func (l Listener) Close() error {
return l.Listener.Close() return l.Listener.Close()
} }
func _server_udp(m *ice.Message, arg ...string) {
l, e := net.ListenUDP("udp4", _broad_addr(m, "0.0.0.0", m.Option(PORT)))
defer l.Close()
mdb.HashCreate(m, arg, kit.Dict(mdb.TARGET, l), STATUS, kit.Select(ERROR, OPEN, e == nil), ERROR, kit.Format(e))
switch cb := m.OptionCB("").(type) {
case func(*net.UDPConn):
m.Assert(e)
cb(l)
}
}
func _server_listen(m *ice.Message, arg ...string) { func _server_listen(m *ice.Message, arg ...string) {
if m.Option("type") == "udp4" {
_server_udp(m, arg...)
return
}
l, e := net.Listen(TCP, m.Option(HOST)+":"+m.Option(PORT)) l, e := net.Listen(TCP, m.Option(HOST)+":"+m.Option(PORT))
l = &Listener{m: m, h: mdb.HashCreate(m, arg, kit.Dict(mdb.TARGET, l), STATUS, kit.Select(ERROR, OPEN, e == nil), ERROR, kit.Format(e)), s: &Stat{}, Listener: l} l = &Listener{m: m, h: mdb.HashCreate(m, arg, kit.Dict(mdb.TARGET, l), STATUS, kit.Select(ERROR, OPEN, e == nil), ERROR, kit.Format(e)), s: &Stat{}, Listener: l}
if e == nil { if e == nil {
@ -63,9 +85,7 @@ const SERVER = "server"
func init() { func init() {
Index.MergeCommands(ice.Commands{ Index.MergeCommands(ice.Commands{
SERVER: {Name: "server hash auto prunes", Help: "服务器", Actions: ice.MergeActions(ice.Actions{ SERVER: {Name: "server hash auto prunes", Help: "服务器", Actions: ice.MergeActions(ice.Actions{
LISTEN: {Name: "listen type name port=9030 host=", Hand: func(m *ice.Message, arg ...string) { LISTEN: {Name: "listen type name port=9030 host=", Hand: func(m *ice.Message, arg ...string) { _server_listen(m, arg...) }},
_server_listen(m, arg...)
}},
}, mdb.StatusHashAction(mdb.FIELD, "time,hash,status,type,name,host,port,error,nconn"), mdb.ClearOnExitHashAction())}, }, mdb.StatusHashAction(mdb.FIELD, "time,hash,status,type,name,host,port,error,nconn"), mdb.ClearOnExitHashAction())},
}) })
} }

View File

@ -29,16 +29,13 @@ func _broad_send(m *ice.Message, host, port string, remote_host, remote_port str
} }
} }
func _broad_serve(m *ice.Message, port string) { func _broad_serve(m *ice.Message, port string) {
if s, e := net.ListenUDP("udp4", _broad_addr(m, "0.0.0.0", port)); m.Assert(e) { m.Cmd(tcp.HOST, func(values ice.Maps) {
defer s.Close()
m.Go(func() {
m.Sleep("10ms").Cmd(tcp.HOST, func(values ice.Maps) {
_broad_send(m, values[aaa.IP], port, "255.255.255.255", "9020", mdb.TYPE, ice.Info.NodeType, mdb.NAME, ice.Info.NodeName) _broad_send(m, values[aaa.IP], port, "255.255.255.255", "9020", mdb.TYPE, ice.Info.NodeType, mdb.NAME, ice.Info.NodeName)
}) })
}) m.Cmd(tcp.SERVER, tcp.LISTEN, mdb.TYPE, "udp4", m.OptionSimple(mdb.NAME, tcp.HOST, tcp.PORT), func(l *net.UDPConn) {
buf := make([]byte, ice.MOD_BUFS) buf := make([]byte, ice.MOD_BUFS)
for { for {
n, from, e := s.ReadFromUDP(buf[:]) n, from, e := l.ReadFromUDP(buf[:])
if e != nil { if e != nil {
break break
} }
@ -51,12 +48,12 @@ func _broad_serve(m *ice.Message, port string) {
if remote := _broad_addr(m, msg.Option(tcp.HOST), msg.Option(tcp.PORT)); remote != nil { if remote := _broad_addr(m, msg.Option(tcp.HOST), msg.Option(tcp.PORT)); remote != nil {
m.Cmd(BROAD, func(value ice.Maps) { m.Cmd(BROAD, func(value ice.Maps) {
m.Logs(tcp.SEND, BROAD, kit.Format(value), nfs.TO, kit.Format(remote)) m.Logs(tcp.SEND, BROAD, kit.Format(value), nfs.TO, kit.Format(remote))
s.WriteToUDP([]byte(m.Spawn(value, kit.Dict(mdb.ZONE, "echo")).FormatMeta()), remote) l.WriteToUDP([]byte(m.Spawn(value, kit.Dict(mdb.ZONE, "echo")).FormatMeta()), remote)
}) })
_broad_save(m, msg) _broad_save(m, msg)
} }
} }
} })
} }
func _broad_save(m, msg *ice.Message) { func _broad_save(m, msg *ice.Message) {
save := false save := false
@ -101,6 +98,9 @@ func init() {
tcp.SEND: {Hand: func(m *ice.Message, arg ...string) { tcp.SEND: {Hand: func(m *ice.Message, arg ...string) {
_broad_send(m, "", "", "255.255.255.255", "9020", arg...) _broad_send(m, "", "", "255.255.255.255", "9020", arg...)
}}, }},
SERVE_START: {Hand: func(m *ice.Message, arg ...string) {
m.Go(func() { m.Cmd(BROAD, SERVE, m.OptionSimple(tcp.PORT)) })
}},
}, mdb.HashAction(mdb.SHORT, "host,port", mdb.FIELD, "time,hash,type,name,host,port", mdb.ACTION, OPEN), mdb.ClearOnExitHashAction())}, }, mdb.HashAction(mdb.SHORT, "host,port", mdb.FIELD, "time,hash,type,name,host,port", mdb.ACTION, OPEN), mdb.ClearOnExitHashAction())},
}) })
} }

View File

@ -137,7 +137,7 @@ func init() {
cli.STOP: {Hand: func(m *ice.Message, arg ...string) { cli.STOP: {Hand: func(m *ice.Message, arg ...string) {
m.Cmd(SPACE, mdb.MODIFY, m.OptionSimple(mdb.NAME), mdb.STATUS, cli.STOP) m.Cmd(SPACE, mdb.MODIFY, m.OptionSimple(mdb.NAME), mdb.STATUS, cli.STOP)
m.Go(func() { m.Cmd(SPACE, m.Option(mdb.NAME), ice.EXIT) }) m.Go(func() { m.Cmd(SPACE, m.Option(mdb.NAME), ice.EXIT) })
m.Sleep("1s") m.Sleep300ms()
}}, }},
nfs.TRASH: {Hand: func(m *ice.Message, arg ...string) { nfs.TRASH: {Hand: func(m *ice.Message, arg ...string) {
nfs.Trash(m, path.Join(ice.USR_LOCAL_WORK, m.Option(mdb.NAME))) nfs.Trash(m, path.Join(ice.USR_LOCAL_WORK, m.Option(mdb.NAME)))

View File

@ -17,7 +17,6 @@ import (
"shylinux.com/x/icebergs/base/gdb" "shylinux.com/x/icebergs/base/gdb"
"shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/nfs" "shylinux.com/x/icebergs/base/nfs"
"shylinux.com/x/icebergs/base/ssh"
"shylinux.com/x/icebergs/base/tcp" "shylinux.com/x/icebergs/base/tcp"
kit "shylinux.com/x/toolkits" kit "shylinux.com/x/toolkits"
) )
@ -26,13 +25,12 @@ func _serve_address(m *ice.Message) string {
return kit.Format("http://localhost:%s", m.Option(tcp.PORT)) return kit.Format("http://localhost:%s", m.Option(tcp.PORT))
} }
func _serve_start(m *ice.Message) { func _serve_start(m *ice.Message) {
defer kit.For(kit.Split(m.Option(ice.DEV)), func(v string) { m.Cmd(SPACE, tcp.DIAL, ice.DEV, v, mdb.NAME, ice.Info.NodeName) }) defer kit.For(kit.Split(m.Option(ice.DEV)), func(v string) { m.Sleep("10ms").Cmd(SPACE, tcp.DIAL, ice.DEV, v, mdb.NAME, ice.Info.NodeName) })
kit.If(m.Option(aaa.USERNAME), func() { aaa.UserRoot(m, m.Option(aaa.USERNICK), m.Option(aaa.USERNAME)) }) kit.If(m.Option(aaa.USERNAME), func() { aaa.UserRoot(m, m.Option(aaa.USERNICK), m.Option(aaa.USERNAME)) })
kit.If(m.Option(tcp.PORT) == tcp.RANDOM, func() { m.Option(tcp.PORT, m.Cmdx(tcp.PORT, aaa.RIGHT)) }) kit.If(m.Option(tcp.PORT) == tcp.RANDOM, func() { m.Option(tcp.PORT, m.Cmdx(tcp.PORT, aaa.RIGHT)) })
kit.If(runtime.GOOS == cli.WINDOWS, func() { m.Cmd(SPIDE, ice.OPS, _serve_address(m)+"/exit").Sleep("300ms") }) kit.If(runtime.GOOS == cli.WINDOWS, func() { m.Cmd(SPIDE, ice.OPS, _serve_address(m)+"/exit").Sleep300ms() })
cli.NodeInfo(m, kit.Select(ice.Info.Hostname, m.Option(tcp.NODENAME)), SERVER) cli.NodeInfo(m, kit.Select(ice.Info.Hostname, m.Option(tcp.NODENAME)), SERVER)
m.Target().Start(m, m.OptionSimple(tcp.HOST, tcp.PORT)...) m.Target().Start(m, m.OptionSimple(tcp.HOST, tcp.PORT)...)
m.Sleep("300ms")
} }
func _serve_main(m *ice.Message, w http.ResponseWriter, r *http.Request) bool { func _serve_main(m *ice.Message, w http.ResponseWriter, r *http.Request) bool {
const ( const (
@ -192,27 +190,21 @@ func init() {
_serve_start(m) _serve_start(m)
}}, }},
SERVE_START: {Hand: func(m *ice.Message, arg ...string) { SERVE_START: {Hand: func(m *ice.Message, arg ...string) {
if m.Go(func() { m.Cmd(BROAD, SERVE, m.OptionSimple(tcp.PORT)) }); m.Option(ice.DEV) == "" { m.Go(func() {
m.Cmd(ssh.PRINTF, kit.Dict(nfs.CONTENT, ice.NL+ice.Render(m, ice.RENDER_QRCODE, tcp.PublishLocalhost(m, _serve_address(m))))).Cmd(ssh.PROMPT, kit.Dict(ice.LOG_DISABLE, ice.TRUE))
}
go func() {
opened := false opened := false
for i := 0; i < 3 && !opened; i++ { for i := 0; i < 3 && !opened; i++ {
m.Sleep("1s").Cmd(SPACE, kit.Dict(ice.LOG_DISABLE, ice.TRUE), func(values ice.Maps) { m.Sleep("1s").Cmd(SPACE, kit.Dict(ice.LOG_DISABLE, ice.TRUE), func(values ice.Maps) {
kit.If(values[mdb.TYPE] == CHROME, func() { opened = true }) kit.If(values[mdb.TYPE] == CHROME, func() { opened = true })
}) })
} }
if opened { kit.If(!opened, func() { cli.Opens(m, _serve_address(m)) })
return })
}
cli.Opens(m, _serve_address(m))
}()
}}, }},
DOMAIN: {Hand: func(m *ice.Message, arg ...string) { DOMAIN: {Hand: func(m *ice.Message, arg ...string) {
kit.If(len(arg) > 0, func() { ice.Info.Domain, ice.Info.Localhost = arg[0], false }) kit.If(len(arg) > 0, func() { ice.Info.Domain, ice.Info.Localhost = arg[0], false })
m.Echo(ice.Info.Domain) m.Echo(ice.Info.Domain)
}}, }},
}, mdb.HashAction(mdb.SHORT, mdb.NAME, mdb.FIELD, "time,status,name,proto,host,port", tcp.LOCALHOST, ice.TRUE), mdb.ClearOnExitHashAction(), ServeAction())}, }, mdb.HashAction(mdb.SHORT, mdb.NAME, mdb.FIELD, "time,status,name,proto,host,port", tcp.LOCALHOST, ice.TRUE), mdb.ClearOnExitHashAction())},
PP(ice.INTSHELL): {Name: "/intshell/", Help: "命令行", Actions: aaa.WhiteAction(), Hand: func(m *ice.Message, arg ...string) { PP(ice.INTSHELL): {Name: "/intshell/", Help: "命令行", Actions: aaa.WhiteAction(), Hand: func(m *ice.Message, arg ...string) {
RenderIndex(m, arg...) RenderIndex(m, arg...)
}}, }},
@ -256,15 +248,6 @@ func init() {
} }
m.RenderDownload(p) m.RenderDownload(p)
}}, }},
PP(ice.HELP): {Name: "/help/", Help: "帮助", Actions: ice.MergeActions(ctx.CmdAction(), aaa.WhiteAction()), Hand: func(m *ice.Message, arg ...string) {
if len(arg) == 0 {
arg = append(arg, "tutor.shy")
}
if len(arg) > 0 && arg[0] != ctx.ACTION {
arg[0] = path.Join(ice.SRC_HELP, arg[0])
}
m.Cmdy("web.chat./cmd/", arg)
}},
}) })
ice.AddMerges(func(c *ice.Context, key string, cmd *ice.Command, sub string, action *ice.Action) (ice.Handler, ice.Handler) { ice.AddMerges(func(c *ice.Context, key string, cmd *ice.Command, sub string, action *ice.Action) (ice.Handler, ice.Handler) {
if strings.HasPrefix(sub, ice.PS) { if strings.HasPrefix(sub, ice.PS) {

View File

@ -33,9 +33,9 @@ func _space_dial(m *ice.Message, dev, name string, arg ...string) {
if conn, _, e := websocket.NewClient(c, uri, nil, kit.Int(redial["r"]), kit.Int(redial["w"])); !m.Warn(e, tcp.DIAL, dev, SPACE, uri.String()) { if conn, _, e := websocket.NewClient(c, uri, nil, kit.Int(redial["r"]), kit.Int(redial["w"])); !m.Warn(e, tcp.DIAL, dev, SPACE, uri.String()) {
defer mdb.HashCreateDeferRemove(m, kit.SimpleKV("", MASTER, dev, msg.Append(tcp.HOSTNAME)), kit.Dict(mdb.TARGET, conn))() defer mdb.HashCreateDeferRemove(m, kit.SimpleKV("", MASTER, dev, msg.Append(tcp.HOSTNAME)), kit.Dict(mdb.TARGET, conn))()
if !prints && ice.Info.Colors { if !prints && ice.Info.Colors {
go func() { m.Go(func() {
m.Sleep("300ms").Cmd(ssh.PRINTF, kit.Dict(nfs.CONTENT, "\r"+ice.Render(m, ice.RENDER_QRCODE, m.CmdAppend(SPACE, dev, cli.PWD, mdb.LINK)))).Cmd(ssh.PROMPT, kit.Dict(ice.LOG_DISABLE, ice.TRUE)) m.Sleep300ms().Cmd(ssh.PRINTF, kit.Dict(nfs.CONTENT, "\r"+ice.Render(m, ice.RENDER_QRCODE, m.CmdAppend(SPACE, dev, cli.PWD, mdb.LINK)))).Cmd(ssh.PROMPT, kit.Dict(ice.LOG_DISABLE, ice.TRUE))
}() })
prints = true prints = true
} }
_space_handle(m.Spawn(), true, dev, conn) _space_handle(m.Spawn(), true, dev, conn)
@ -57,8 +57,8 @@ func _space_fork(m *ice.Message) {
case WORKER: case WORKER:
defer gdb.EventDeferEvent(m, DREAM_OPEN, args)(DREAM_CLOSE, args) defer gdb.EventDeferEvent(m, DREAM_OPEN, args)(DREAM_CLOSE, args)
case CHROME: case CHROME:
m.Go(func() { m.Sleep30ms().Cmd(SPACE, name, cli.PWD, name) }) m.Cmd(SPACE, name, cli.PWD, name)
case aaa.LOGIN: case LOGIN:
gdb.EventDeferEvent(m, SPACE_LOGIN, args) gdb.EventDeferEvent(m, SPACE_LOGIN, args)
} }
_space_handle(m, false, name, conn) _space_handle(m, false, name, conn)
@ -66,10 +66,10 @@ func _space_fork(m *ice.Message) {
} }
} }
func _space_handle(m *ice.Message, safe bool, name string, conn *websocket.Conn) { func _space_handle(m *ice.Message, safe bool, name string, conn *websocket.Conn) {
defer m.Cost(SPACE, name)
for { for {
_, b, e := conn.ReadMessage() _, b, e := conn.ReadMessage()
if e != nil { if e != nil {
m.Cost(SPACE, name, e)
break break
} }
msg := m.Spawn(b) msg := m.Spawn(b)
@ -89,7 +89,7 @@ func _space_handle(m *ice.Message, safe bool, name string, conn *websocket.Conn)
}) { }) {
} else if res := getSend(m, next); !m.Warn(res == nil || len(target) != 1, ice.ErrNotFound, next) { } else if res := getSend(m, next); !m.Warn(res == nil || len(target) != 1, ice.ErrNotFound, next) {
res.Cost(kit.Format("[%v]->%v %v %v", next, res.Optionv(ice.MSG_TARGET), res.Detailv(), msg.FormatSize())) res.Cost(kit.Format("[%v]->%v %v %v", next, res.Optionv(ice.MSG_TARGET), res.Detailv(), msg.FormatSize()))
back(res, msg.Sleep("10ms")) // 接收响应 back(res, msg.Sleep30ms()) // 接收响应
} }
} }
} }
@ -189,7 +189,6 @@ func init() {
m.PushSearch(mdb.TEXT, m.Cmd(SPIDE, values[mdb.NAME], ice.Maps{ice.MSG_FIELDS: ""}).Append(CLIENT_ORIGIN), values) m.PushSearch(mdb.TEXT, m.Cmd(SPIDE, values[mdb.NAME], ice.Maps{ice.MSG_FIELDS: ""}).Append(CLIENT_ORIGIN), values)
case SERVER: case SERVER:
m.PushSearch(mdb.TEXT, kit.Format(tcp.PublishLocalhost(m, strings.Split(MergePod(m, values[mdb.NAME]), ice.QS)[0])), values) m.PushSearch(mdb.TEXT, kit.Format(tcp.PublishLocalhost(m, strings.Split(MergePod(m, values[mdb.NAME]), ice.QS)[0])), values)
case aaa.LOGIN:
} }
}) })
} else if arg[0] == mdb.FOREACH && arg[1] == ssh.SHELL { } else if arg[0] == mdb.FOREACH && arg[1] == ssh.SHELL {
@ -208,7 +207,7 @@ func init() {
} }
aaa.SessAuth(m, kit.Dict(aaa.USERNAME, m.Option(ice.MSG_USERNAME), aaa.USERNICK, m.Option(ice.MSG_USERNICK), aaa.USERROLE, m.Option(ice.MSG_USERROLE))) aaa.SessAuth(m, kit.Dict(aaa.USERNAME, m.Option(ice.MSG_USERNAME), aaa.USERNICK, m.Option(ice.MSG_USERNICK), aaa.USERROLE, m.Option(ice.MSG_USERROLE)))
}}, }},
aaa.LOGIN: {Hand: func(m *ice.Message, arg ...string) { LOGIN: {Hand: func(m *ice.Message, arg ...string) {
m.Cmd(SPACE, kit.Select(m.Option(mdb.NAME), arg, 0), ice.MSG_SESSID, aaa.SessCreate(m, m.Option(ice.MSG_USERNAME))) m.Cmd(SPACE, kit.Select(m.Option(mdb.NAME), arg, 0), ice.MSG_SESSID, aaa.SessCreate(m, m.Option(ice.MSG_USERNAME)))
}}, }},
DOMAIN: {Hand: func(m *ice.Message, arg ...string) { m.Echo(_space_domain(m)) }}, DOMAIN: {Hand: func(m *ice.Message, arg ...string) { m.Echo(_space_domain(m)) }},
@ -228,8 +227,8 @@ func init() {
mdb.HashSelect(m, arg...).Sort("type,name,text") mdb.HashSelect(m, arg...).Sort("type,name,text")
m.Tables(func(values ice.Maps) { m.Tables(func(values ice.Maps) {
switch values[mdb.TYPE] { switch values[mdb.TYPE] {
case aaa.LOGIN: case LOGIN:
m.PushButton(aaa.LOGIN, mdb.REMOVE) m.PushButton(LOGIN, mdb.REMOVE)
default: default:
m.PushButton(cli.OPEN, mdb.REMOVE) m.PushButton(cli.OPEN, mdb.REMOVE)
} }

View File

@ -23,11 +23,10 @@ type Frame struct {
send ice.Messages send ice.Messages
} }
func (f *Frame) Begin(m *ice.Message, arg ...string) ice.Server { func (f *Frame) Begin(m *ice.Message, arg ...string) {
f.send = ice.Messages{} f.send = ice.Messages{}
return f
} }
func (f *Frame) Start(m *ice.Message, arg ...string) bool { func (f *Frame) Start(m *ice.Message, arg ...string) {
f.Message, f.Server = m, &http.Server{Handler: f} f.Message, f.Server = m, &http.Server{Handler: f}
list := map[*ice.Context]string{} list := map[*ice.Context]string{}
m.Travel(func(p *ice.Context, c *ice.Context) { m.Travel(func(p *ice.Context, c *ice.Context) {
@ -56,24 +55,18 @@ func (f *Frame) Start(m *ice.Message, arg ...string) bool {
}(key, cmd) }(key, cmd)
} }
}) })
gdb.EventDeferEvent(m, SERVE_START, arg)
switch cb := m.OptionCB("").(type) { switch cb := m.OptionCB("").(type) {
case func(http.Handler): case func(http.Handler):
cb(f) cb(f)
default: default:
m.Cmd(tcp.SERVER, tcp.LISTEN, mdb.TYPE, WEB, m.OptionSimple(mdb.NAME, tcp.HOST, tcp.PORT), func(l net.Listener) { m.Cmd(tcp.SERVER, tcp.LISTEN, mdb.TYPE, WEB, m.OptionSimple(mdb.NAME, tcp.HOST, tcp.PORT), func(l net.Listener) {
defer mdb.HashCreateDeferRemove(m, m.OptionSimple(mdb.NAME, tcp.PROTO), arg, cli.STATUS, tcp.START)() defer mdb.HashCreateDeferRemove(m, m.OptionSimple(mdb.NAME, tcp.PROTO), arg, cli.STATUS, tcp.START)()
gdb.EventDeferEvent(m, SERVE_START, arg)
m.Warn(f.Server.Serve(l)) m.Warn(f.Server.Serve(l))
}) })
} }
return true
}
func (f *Frame) Close(m *ice.Message, arg ...string) bool {
return true
}
func (f *Frame) Spawn(m *ice.Message, c *ice.Context, arg ...string) ice.Server {
return &Frame{}
} }
func (f *Frame) Close(m *ice.Message, arg ...string) {}
func (f *Frame) ServeHTTP(w http.ResponseWriter, r *http.Request) { func (f *Frame) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if _serve_main(f.Message, w, r) { if _serve_main(f.Message, w, r) {
f.ServeMux.ServeHTTP(w, r) f.ServeMux.ServeHTTP(w, r)

View File

@ -23,9 +23,6 @@ func init() {
} }
} }
}}, }},
ice.HELP: {Hand: func(m *ice.Message, arg ...string) {
ctx.ProcessField(m, web.WIKI_WORD, func() string { return kit.ExtChange(ctx.GetCmdFile(m, arg[0]), nfs.SHY) }, arg...)
}},
nfs.SCRIPT: {Hand: func(m *ice.Message, arg ...string) { nfs.SCRIPT: {Hand: func(m *ice.Message, arg ...string) {
ctx.ProcessField(m, web.CODE_VIMER, func() []string { ctx.ProcessField(m, web.CODE_VIMER, func() []string {
return nfs.SplitPath(m, kit.ExtChange(nfs.Relative(m, ctx.GetCmdFile(m, arg[0])), nfs.JS)) return nfs.SplitPath(m, kit.ExtChange(nfs.Relative(m, ctx.GetCmdFile(m, arg[0])), nfs.JS))

View File

@ -34,7 +34,11 @@ func _header_share(m *ice.Message, arg ...string) {
m.Push(mdb.NAME, m.Option(mdb.LINK)).PushQRCode(mdb.TEXT, m.Option(mdb.LINK)) m.Push(mdb.NAME, m.Option(mdb.LINK)).PushQRCode(mdb.TEXT, m.Option(mdb.LINK))
} }
func _header_check(m *ice.Message, arg ...string) bool { func _header_check(m *ice.Message, arg ...string) bool {
if m.Option(web.SHARE) != "" { if m.Option(ice.CMD) == aaa.OFFER && m.Option(mdb.HASH) != "" {
m.Cmd(aaa.OFFER, m.Option(mdb.HASH), func(value ice.Maps) {
aaa.SessAuth(m, kit.Dict(aaa.USERNAME, value[aaa.EMAIL], aaa.USERROLE, aaa.VOID))
})
} else if m.Option(web.SHARE) != "" {
m.Cmd(web.SHARE, m.Option(web.SHARE), ice.OptionFields(""), func(value ice.Maps) { m.Cmd(web.SHARE, m.Option(web.SHARE), ice.OptionFields(""), func(value ice.Maps) {
if web.IsNotValidShare(m, value[mdb.TIME]) { if web.IsNotValidShare(m, value[mdb.TIME]) {
return return
@ -65,6 +69,7 @@ const HEADER = "header"
func init() { func init() {
Index.MergeCommands(ice.Commands{ Index.MergeCommands(ice.Commands{
web.P(HEADER): {Name: "/header", Help: "标题栏", Actions: ice.MergeActions(ice.Actions{ web.P(HEADER): {Name: "/header", Help: "标题栏", Actions: ice.MergeActions(ice.Actions{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { aaa.White(m, HEADER) }},
mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) {}}, mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) {}},
aaa.LOGOUT: {Hand: aaa.SessLogout}, aaa.LOGOUT: {Hand: aaa.SessLogout},
aaa.PASSWORD: {Hand: _header_users}, aaa.PASSWORD: {Hand: _header_users},
@ -74,14 +79,12 @@ func init() {
aaa.AVATAR: {Hand: _header_users}, aaa.AVATAR: {Hand: _header_users},
web.SHARE: {Hand: _header_share}, web.SHARE: {Hand: _header_share},
"webpack": {Hand: ctx.CmdHandler("webpack", "build")}, "webpack": {Hand: ctx.CmdHandler("webpack", "build")},
}, ctx.ConfAction(SSO, ""), aaa.BlackAction("webpack")), Hand: func(m *ice.Message, arg ...string) { }, ctx.ConfAction(SSO, "")), Hand: func(m *ice.Message, arg ...string) {
if gdb.Event(m, HEADER_AGENT); !_header_check(m, arg...) { if gdb.Event(m, HEADER_AGENT); !_header_check(m, arg...) {
return return
} }
msg := m.Cmd(aaa.USER, m.Option(ice.MSG_USERNAME)) msg := m.Cmd(aaa.USER, m.Option(ice.MSG_USERNAME))
for _, k := range []string{aaa.USERNICK, aaa.LANGUAGE} { kit.For([]string{aaa.USERNICK, aaa.LANGUAGE}, func(k string) { m.Option(k, msg.Append(k)) })
m.Option(k, msg.Append(k))
}
for _, k := range []string{aaa.BACKGROUND, aaa.AVATAR} { for _, k := range []string{aaa.BACKGROUND, aaa.AVATAR} {
if strings.HasPrefix(msg.Append(k), ice.PS) || strings.HasPrefix(msg.Append(k), ice.HTTP) { if strings.HasPrefix(msg.Append(k), ice.PS) || strings.HasPrefix(msg.Append(k), ice.HTTP) {
m.Option(k, msg.Append(k)) m.Option(k, msg.Append(k))

View File

@ -14,6 +14,7 @@ func init() {
Index.MergeCommands(ice.Commands{ Index.MergeCommands(ice.Commands{
TEMPLATE: {Name: "template river storm index auto 删除配置 查看配置", Help: "模板", Actions: ice.MergeActions(ice.Actions{ TEMPLATE: {Name: "template river storm index auto 删除配置 查看配置", Help: "模板", Actions: ice.MergeActions(ice.Actions{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
return
if gdb.Watch(m, RIVER_CREATE); m.Cmd("").Length() == 0 { if gdb.Watch(m, RIVER_CREATE); m.Cmd("").Length() == 0 {
kit.For(_river_template, func(river string, value ice.Any) { kit.For(_river_template, func(river string, value ice.Any) {
m.Cmd("", mdb.CREATE, RIVER, river) m.Cmd("", mdb.CREATE, RIVER, river)

View File

@ -52,7 +52,7 @@ func init() {
u := web.OptionUserWeb(m) u := web.OptionUserWeb(m)
p := u.Hostname() + ice.DF + m.Cmdx(tcp.PORT, aaa.RIGHT) p := u.Hostname() + ice.DF + m.Cmdx(tcp.PORT, aaa.RIGHT)
m.Cmd(cli.DAEMON, mdb.Configv(m, PPROF), "-http="+p, m.Option(BINNARY), m.Option(nfs.FILE)) m.Cmd(cli.DAEMON, mdb.Configv(m, PPROF), "-http="+p, m.Option(BINNARY), m.Option(nfs.FILE))
m.Sleep("3s").ProcessOpen(kit.Format("http://%s/ui/top", p)) m.Sleep3s().ProcessOpen(kit.Format("http://%s/ui/top", p))
}}, }},
}, mdb.ZoneAction(mdb.FIELDS, "time,zone,count,binnary,service,seconds", mdb.FIELD, "time,id,text,file", PPROF, kit.List(GO, "tool", PPROF))), Hand: func(m *ice.Message, arg ...string) { }, mdb.ZoneAction(mdb.FIELDS, "time,zone,count,binnary,service,seconds", mdb.FIELD, "time,id,text,file", PPROF, kit.List(GO, "tool", PPROF))), Hand: func(m *ice.Message, arg ...string) {
if mdb.ZoneSelect(m, arg...); len(arg) == 0 { if mdb.ZoneSelect(m, arg...); len(arg) == 0 {

View File

@ -154,7 +154,7 @@ func init() {
if isWebview() { if isWebview() {
m.Go(func() { m.Cmd(cli.SYSTEM, "./bin/ice.bin", cli.FOREVER, cli.DELAY, "300ms", cli.SYSTEM, cli.OPEN, app) }) m.Go(func() { m.Cmd(cli.SYSTEM, "./bin/ice.bin", cli.FOREVER, cli.DELAY, "300ms", cli.SYSTEM, cli.OPEN, app) })
} }
m.Go(func() { m.Sleep("10ms").Cmd(UPGRADE, cli.RESTART) }) m.Go(func() { m.Sleep30ms().Cmd(UPGRADE, cli.RESTART) })
} else { } else {
_vimer_make(m, nfs.PWD, msg) _vimer_make(m, nfs.PWD, msg)
} }

View File

@ -59,7 +59,7 @@ func _xterm_get(m *ice.Message, h string) _xterm {
if _xterm_echo(m, h, string(buf[:n])); len(text) > 0 { if _xterm_echo(m, h, string(buf[:n])); len(text) > 0 {
if cmd := text[0]; text[0] != "" { if cmd := text[0]; text[0] != "" {
m.Go(func() { m.Go(func() {
m.Sleep("10ms") m.Sleep30ms()
tty.Write([]byte(cmd + ice.NL)) tty.Write([]byte(cmd + ice.NL))
}) })
} }

View File

@ -76,8 +76,9 @@ func (m *Message) TableGo(cb Any) *Message {
}) })
return m return m
} }
func (m *Message) Go(cb Any) *Message { func (m *Message) Go(cb Any, arg ...Any) *Message {
task.Put(logs.FileLine(cb), func(task *task.Task) error { kit.If(len(arg) == 0, func() { arg = append(arg, logs.FileLine(cb)) })
task.Put(arg[0], func(task *task.Task) error {
m.TryCatch(m, true, func(m *Message) { m.TryCatch(m, true, func(m *Message) {
switch cb := cb.(type) { switch cb := cb.(type) {
case func(*Message): case func(*Message):

69
init.go
View File

@ -13,7 +13,7 @@ import (
type Frame struct{} type Frame struct{}
func (s *Frame) Begin(m *Message, arg ...string) Server { func (s *Frame) Begin(m *Message, arg ...string) {
list := map[*Context]*Message{m.target: m} list := map[*Context]*Message{m.target: m}
m.Travel(func(p *Context, s *Context) { m.Travel(func(p *Context, s *Context) {
s.root = m.target s.root = m.target
@ -22,19 +22,14 @@ func (s *Frame) Begin(m *Message, arg ...string) Server {
s.Begin(list[s], arg...) s.Begin(list[s], arg...)
} }
}) })
return s
} }
func (s *Frame) Start(m *Message, arg ...string) bool { func (s *Frame) Start(m *Message, arg ...string) {
m.Cap(CTX_STREAM, strings.Split(m.Time(), SP)[1])
m.Cmd(kit.Keys(MDB, CTX_INIT)) m.Cmd(kit.Keys(MDB, CTX_INIT))
m.Cmd(INIT, arg) m.Cmd(INIT, arg)
for _, k := range kit.Split(kit.Select("ctx,log,gdb,ssh", os.Getenv(CTX_DAEMON))) {
m.Start(k)
}
m.Cmd(arg) m.Cmd(arg)
return true kit.For(kit.Split(kit.Select("log,gdb,ssh", os.Getenv(CTX_DAEMON))), func(k string) { m.Sleep("10ms").Start(k) })
} }
func (s *Frame) Close(m *Message, arg ...string) bool { func (s *Frame) Close(m *Message, arg ...string) {
list := map[*Context]*Message{m.target: m} list := map[*Context]*Message{m.target: m}
m.Travel(func(p *Context, s *Context) { m.Travel(func(p *Context, s *Context) {
if msg, ok := list[p]; ok && msg != nil { if msg, ok := list[p]; ok && msg != nil {
@ -43,26 +38,25 @@ func (s *Frame) Close(m *Message, arg ...string) bool {
} }
}) })
conf.Close() conf.Close()
go func() { os.Exit(kit.Int(Pulse.Sleep("30ms").Option(EXIT))) }() go func() { os.Exit(kit.Int(Pulse.Sleep30ms().Option(EXIT))) }()
return true
} }
func (s *Frame) Spawn(m *Message, c *Context, arg ...string) Server { return &Frame{} }
const ( const (
INIT = "init" INIT = "init"
HELP = "help"
EXIT = "exit"
QUIT = "quit" QUIT = "quit"
EXIT = "exit"
) )
var Index = &Context{Name: ICE, Help: "冰山模块", Configs: Configs{HELP: {Value: kit.Data(INDEX, Info.Help)}}, Commands: Commands{ var Index = &Context{Name: ICE, Help: "冰山模块", Commands: Commands{
CTX_INIT: {Hand: func(m *Message, arg ...string) { CTX_INIT: {Hand: func(m *Message, arg ...string) {
m.Travel(func(p *Context, c *Context) { m.Travel(func(p *Context, c *Context) {
if p != nil { kit.If(p != nil, func() { m.Go(func() { c._command(m.Spawn(c), c.Commands[CTX_INIT], CTX_INIT, arg...) }) })
c._command(m.Spawn(c), c.Commands[CTX_INIT], CTX_INIT, arg...)
}
}) })
loadImportant(m) loadImportant(m)
loadImportant(m)
loadImportant(m)
loadImportant(m)
loadImportant(m)
}}, }},
INIT: {Hand: func(m *Message, arg ...string) { INIT: {Hand: func(m *Message, arg ...string) {
m.Cmd(CTX_INIT) m.Cmd(CTX_INIT)
@ -77,25 +71,22 @@ var Index = &Context{Name: ICE, Help: "冰山模块", Configs: Configs{HELP: {Va
CTX_EXIT: {Hand: func(m *Message, arg ...string) { CTX_EXIT: {Hand: func(m *Message, arg ...string) {
defer m.Target().Close(m.Spawn(), arg...) defer m.Target().Close(m.Spawn(), arg...)
m.Travel(func(p *Context, c *Context) { m.Travel(func(p *Context, c *Context) {
if p != nil { kit.If(p != nil, func() { c._command(m.Spawn(c), c.Commands[CTX_EXIT], CTX_EXIT, arg...) })
c._command(m.Spawn(c), c.Commands[CTX_EXIT], CTX_EXIT, arg...)
}
}) })
removeImportant(m) removeImportant(m)
}}, }},
}, server: &Frame{}} }, server: &Frame{}}
var Pulse = &Message{time: time.Now(), code: 0, meta: map[string][]string{}, data: Map{}, source: Index, target: Index, Hand: true} var Pulse = &Message{time: time.Now(), code: 0, Hand: true, meta: map[string][]string{}, data: Map{}, source: Index, target: Index}
func init() { Index.root, Pulse.root = Index, Pulse } func init() { Index.root, Pulse.root = Index, Pulse }
func Run(arg ...string) string { func Run(arg ...string) string {
if len(arg) == 0 && len(os.Args) > 1 { kit.If(len(arg) == 0 && len(os.Args) > 1, func() { arg = kit.Simple(os.Args[1:], kit.Split(kit.Env(CTX_ARG))) })
arg = kit.Simple(os.Args[1:], kit.Split(kit.Env(CTX_ARG)))
}
if len(arg) == 0 { if len(arg) == 0 {
if runtime.GOOS == "windows" { if runtime.GOOS == "windows" {
arg = append(arg, SERVE, START, DEV, DEV) arg = append(arg, SERVE, START, DEV, DEV)
} else { } else {
arg = append(arg, "pwd")
// arg = append(arg, "forever", START, DEV, DEV) // arg = append(arg, "forever", START, DEV, DEV)
} }
} }
@ -105,32 +96,20 @@ func Run(arg ...string) string {
Pulse.Option(ls[0], ls[1]) Pulse.Option(ls[0], ls[1])
} }
}) })
kit.If(Pulse._cmd == nil, func() { Pulse._cmd = &Command{RawHand: logs.FileLines(3)} })
time.Local = time.FixedZone("Beijing", 28800) time.Local = time.FixedZone("Beijing", 28800)
if Pulse.time = time.Now(); Pulse._cmd == nil { Pulse.time = time.Now()
Pulse._cmd = &Command{RawHand: logs.FileLines(3)}
}
switch Index.Merge(Index).Begin(Pulse, arg...); kit.Select("", arg, 0) { switch Index.Merge(Index).Begin(Pulse, arg...); kit.Select("", arg, 0) {
case SERVE, SPACE: case SERVE, SPACE:
if os.Getenv("ctx_log") == "" { Index.Start(Pulse, arg...)
// os.Stderr.Close()
}
if Index.Start(Pulse, arg...) {
conf.Wait() conf.Wait()
os.Exit(kit.Int(Pulse.Option(EXIT))) os.Exit(kit.Int(Pulse.Option(EXIT)))
}
default: default:
if logs.Disable(true); len(arg) == 0 { logs.Disable(true)
arg = append(arg, HELP) Pulse.Cmdy(INIT).Cmdy(arg)
} kit.If(Pulse.IsErrNotFound(), func() { Pulse.SetAppend().SetResult().Cmdy(SYSTEM, arg) })
if Pulse.Cmdy(INIT).Cmdy(arg); Pulse.IsErrNotFound() { kit.If(strings.TrimSpace(Pulse.Result()) == "" && Pulse.Length() > 0, func() { Pulse.Table() })
Pulse.SetAppend().SetResult().Cmdy(SYSTEM, arg) kit.If(Pulse.Result() != "" && !strings.HasSuffix(Pulse.Result(), NL), func() { Pulse.Echo(NL) })
}
if strings.TrimSpace(Pulse.Result()) == "" && Pulse.Length() > 0 {
Pulse.Table()
}
if Pulse.Result() != "" && !strings.HasSuffix(Pulse.Result(), NL) {
Pulse.Echo(NL)
}
} }
return Pulse.Result() return Pulse.Result()
} }

19
logs.go
View File

@ -272,3 +272,22 @@ func (m *Message) FormatStack(s, n int) string {
} }
return kit.Join(list, NL) return kit.Join(list, NL)
} }
func (c *Command) GetFileLine() string {
return kit.Join(kit.Slice(kit.Split(c.GetFileLines(), PS), -3), PS)
}
func (c *Command) GetFileLines() string {
if c == nil {
return ""
} else if c.RawHand != nil {
switch h := c.RawHand.(type) {
case string:
return h
default:
return logs.FileLines(c.RawHand)
}
} else if c.Hand != nil {
return logs.FileLines(c.Hand)
} else {
return ""
}
}

12
misc.go
View File

@ -351,8 +351,8 @@ func MergeActions(arg ...Any) Actions {
last := h.Hand last := h.Hand
hand := v.Hand hand := v.Hand
h.Hand = func(m *Message, arg ...string) { h.Hand = func(m *Message, arg ...string) {
hand(m, arg...)
last(m, arg...) last(m, arg...)
hand(m, arg...)
} }
} else if h.Name = kit.Select(v.Name, h.Name); h.Hand == nil { } else if h.Name = kit.Select(v.Name, h.Name); h.Hand == nil {
h.Hand = v.Hand h.Hand = v.Hand
@ -474,3 +474,13 @@ func MergeHand(hand ...Handler) Handler {
} }
} }
} }
func (m *Message) CmdMap(arg ...string) map[string]map[string]string {
field, list := kit.Slice(arg, -1)[0], map[string]map[string]string{}
m._command(kit.Slice(arg, 0, -1)).Tables(func(value Maps) { list[value[field]] = value })
return list
}
func (m *Message) CmdAppend(arg ...Any) string {
args := kit.Simple(arg...)
field := kit.Slice(args, -1)[0]
return m._command(kit.Slice(args, 0, -1), OptionFields(field)).Append(field)
}

View File

@ -216,13 +216,13 @@ func init() {
PULL: {Help: "下载", Hand: func(m *ice.Message, arg ...string) { PULL: {Help: "下载", Hand: func(m *ice.Message, arg ...string) {
_status_each(m, "", cli.SYSTEM, GIT, PULL) _status_each(m, "", cli.SYSTEM, GIT, PULL)
_status_each(m, "", cli.SYSTEM, GIT, PULL, "--tags") _status_each(m, "", cli.SYSTEM, GIT, PULL, "--tags")
m.Sleep("3s") m.Sleep3s()
}}, }},
PUSH: {Help: "上传", Hand: func(m *ice.Message, arg ...string) { PUSH: {Help: "上传", Hand: func(m *ice.Message, arg ...string) {
if m.Option(REPOS) == "" { if m.Option(REPOS) == "" {
_status_each(m, "", cli.SYSTEM, GIT, PUSH) _status_each(m, "", cli.SYSTEM, GIT, PUSH)
_status_each(m, "", cli.SYSTEM, GIT, PUSH, "--tags") _status_each(m, "", cli.SYSTEM, GIT, PUSH, "--tags")
m.Sleep("3s") m.Sleep3s()
return return
} }
m.Option(cli.CMD_DIR, _repos_path(m.Option(REPOS))) m.Option(cli.CMD_DIR, _repos_path(m.Option(REPOS)))

View File

@ -117,7 +117,7 @@ func init() {
return return
} }
m.Go(func() { m.Go(func() {
m.Sleep("1s") m.Sleep300ms()
_tmux_cmd(m, SEND_KEYS, "-t", kit.Keys(name, "2"), "ish_miss_log", ENTER) _tmux_cmd(m, SEND_KEYS, "-t", kit.Keys(name, "2"), "ish_miss_log", ENTER)
_tmux_cmd(m, SEND_KEYS, "-t", kit.Keys(name, "1"), "vi etc/miss.sh", ENTER) _tmux_cmd(m, SEND_KEYS, "-t", kit.Keys(name, "1"), "vi etc/miss.sh", ENTER)
}) })

View File

@ -126,6 +126,19 @@ func (m *Message) IsCliUA() bool {
func (m *Message) IsMobileUA() bool { func (m *Message) IsMobileUA() bool {
return strings.Contains(m.Option(MSG_USERUA), "Mobile") return strings.Contains(m.Option(MSG_USERUA), "Mobile")
} }
func (m *Message) MergePodCmd(pod, cmd string, arg ...Any) string {
ls := []string{"chat"}
kit.If(kit.Keys(m.Option(MSG_USERPOD), pod), func(p string) { ls = append(ls, POD, p) })
if cmd == "" {
if _, ok := Info.Index[m.CommandKey()]; ok {
cmd = m.CommandKey()
} else {
cmd = m.PrefixKey()
}
}
ls = append(ls, CMD, cmd)
return kit.MergeURL2(strings.Split(kit.Select(Info.Domain, m.Option(MSG_USERWEB)), QS)[0], PS+kit.Join(ls, PS), arg...)
}
func (m *Message) PushSearch(arg ...Any) { func (m *Message) PushSearch(arg ...Any) {
data := kit.Dict(arg...) data := kit.Dict(arg...)
for i := 0; i < len(arg); i += 2 { for i := 0; i < len(arg); i += 2 {

299
type.go
View File

@ -66,65 +66,31 @@ type Context struct {
id int32 id int32
} }
type Server interface { type Server interface {
Begin(m *Message, arg ...string) Server Begin(m *Message, arg ...string)
Start(m *Message, arg ...string) bool Start(m *Message, arg ...string)
Close(m *Message, arg ...string) bool Close(m *Message, arg ...string)
Spawn(m *Message, c *Context, arg ...string) Server
} }
func (c *Context) ID() int32 {
return atomic.AddInt32(&c.id, 1)
}
func (c *Context) Cap(key string, arg ...Any) string { func (c *Context) Cap(key string, arg ...Any) string {
if len(arg) > 0 { kit.If(len(arg) > 0, func() { c.Caches[key].Value = kit.Format(arg[0]) })
c.Caches[key].Value = kit.Format(arg[0])
}
return c.Caches[key].Value return c.Caches[key].Value
} }
func (c *Context) Cmd(m *Message, key string, arg ...string) *Message { func (c *Context) Cmd(m *Message, key string, arg ...string) *Message {
return c._command(m, c.Commands[key], key, arg...) return c._command(m, c.Commands[key], key, arg...)
} }
func (c *Context) Server() Server {
return c.server
}
func (c *Context) Prefix(arg ...string) string { func (c *Context) Prefix(arg ...string) string {
return kit.Keys(c.Cap(CTX_FOLLOW), arg) return kit.Keys(c.Cap(CTX_FOLLOW), arg)
} }
func (c *Command) GetFileLine() string { func (c *Context) Server() Server { return c.server }
return kit.Join(kit.Slice(kit.Split(c.GetFileLines(), PS), -3), PS) func (c *Context) ID() int32 { return atomic.AddInt32(&c.id, 1) }
} func (c *Context) Register(s *Context, x Server, cmd ...string) *Context {
func (c *Command) GetFileLines() string { kit.For(cmd, func(cmd string) {
if c == nil { if s, ok := Info.Index[cmd].(*Context); ok {
return "" panic(kit.Format("%s %s registed by %v", ErrWarn, cmd, s.Name))
} else if c.RawHand != nil {
switch h := c.RawHand.(type) {
case string:
return h
default:
return logs.FileLines(c.RawHand)
}
} else if c.Hand != nil {
return logs.FileLines(c.Hand)
} else {
return ""
}
}
func (c *Context) Register(s *Context, x Server, n ...string) *Context {
for _, n := range n {
if s, ok := Info.Index[n]; ok {
last := ""
switch s := s.(type) {
case *Context:
last = s.Name
}
panic(kit.Format("%s %s %v", ErrWarn, n, last))
}
Info.Index[n] = s
}
if c.Contexts == nil {
c.Contexts = Contexts{}
} }
Info.Index[cmd] = s
})
kit.If(c.Contexts == nil, func() { c.Contexts = Contexts{} })
c.Contexts[s.Name] = s c.Contexts[s.Name] = s
s.root = c.root s.root = c.root
s.context = c s.context = c
@ -134,8 +100,7 @@ func (c *Context) Register(s *Context, x Server, n ...string) *Context {
func (c *Context) MergeCommands(Commands Commands) *Context { func (c *Context) MergeCommands(Commands Commands) *Context {
for key, cmd := range Commands { for key, cmd := range Commands {
if cmd.Hand == nil && cmd.RawHand == nil { if cmd.Hand == nil && cmd.RawHand == nil {
cmd.RawHand = logs.FileLines(2) if cmd.RawHand = logs.FileLines(2); cmd.Actions != nil {
if cmd.Actions != nil {
if action, ok := cmd.Actions[SELECT]; ok { if action, ok := cmd.Actions[SELECT]; ok {
cmd.Name = kit.Select(strings.Replace(action.Name, SELECT, key, 1), cmd.Name) cmd.Name = kit.Select(strings.Replace(action.Name, SELECT, key, 1), cmd.Name)
cmd.Help = kit.Select(action.Help, cmd.Help) cmd.Help = kit.Select(action.Help, cmd.Help)
@ -144,65 +109,49 @@ func (c *Context) MergeCommands(Commands Commands) *Context {
} }
} }
configs := Configs{} configs := Configs{}
for k, _ := range Commands { for k := range Commands {
configs[k] = &Config{Value: kit.Data()} configs[k] = &Config{Value: kit.Data()}
} }
return c.Merge(&Context{Commands: Commands, Configs: configs}) return c.Merge(&Context{Commands: Commands, Configs: configs})
} }
func (c *Context) Merge(s *Context) *Context { func (c *Context) Merge(s *Context) *Context {
if c.Commands == nil { kit.If(c.Commands == nil, func() { c.Commands = Commands{} })
c.Commands = Commands{} kit.If(c.Commands[CTX_INIT] == nil, func() { c.Commands[CTX_INIT] = &Command{Hand: func(m *Message, arg ...string) { Info.Load(m) }} })
kit.If(c.Commands[CTX_EXIT] == nil, func() { c.Commands[CTX_EXIT] = &Command{Hand: func(m *Message, arg ...string) { Info.Save(m) }} })
merge := func(pre *Command, init bool, key string, cmd *Command, cb Handler) {
if cb == nil {
return
} }
if c.Commands[CTX_INIT] == nil {
c.Commands[CTX_INIT] = &Command{Hand: func(m *Message, arg ...string) { Info.Load(m) }}
}
if c.Commands[CTX_EXIT] == nil {
c.Commands[CTX_EXIT] = &Command{Hand: func(m *Message, arg ...string) { Info.Save(m) }}
}
merge := func(pre *Command, init bool, key string, cmd *Command, cb ...Handler) {
last := pre.Hand last := pre.Hand
pre.Hand = func(m *Message, arg ...string) { pre.Hand = func(m *Message, arg ...string) {
if init { kit.If(init, func() { last(m, arg...) })
last(m, arg...) defer kit.If(!init, func() { last(m, arg...) })
}
_key, _cmd := m._key, m._cmd _key, _cmd := m._key, m._cmd
defer func() { m._key, m._cmd = _key, _cmd }()
m._key, m._cmd = key, cmd m._key, m._cmd = key, cmd
for _, cb := range cb {
if cb != nil {
cb(m, arg...) cb(m, arg...)
} }
} }
m._key, m._cmd = _key, _cmd
if !init {
last(m, arg...)
}
}
}
for key, cmd := range s.Commands { for key, cmd := range s.Commands {
if pre, ok := c.Commands[key]; ok && s != c { if pre, ok := c.Commands[key]; ok && s != c {
switch hand := cmd.Hand; key { switch key {
case CTX_INIT: case CTX_INIT:
merge(pre, true, key, cmd, hand) merge(pre, true, key, cmd, cmd.Hand)
continue continue
case CTX_EXIT: case CTX_EXIT:
merge(pre, false, key, cmd, hand) merge(pre, false, key, cmd, cmd.Hand)
continue continue
} }
} }
if c.Commands[key] = cmd; cmd.List == nil { c.Commands[key] = cmd
cmd.List = SplitCmd(cmd.Name, cmd.Actions) kit.If(cmd.Meta == nil, func() { cmd.Meta = kit.Dict() })
} kit.If(cmd.List == nil, func() { cmd.List = SplitCmd(cmd.Name, cmd.Actions) })
if cmd.Meta == nil {
cmd.Meta = kit.Dict()
}
for sub, action := range cmd.Actions { for sub, action := range cmd.Actions {
if pre, ok := c.Commands[sub]; ok && s == c { if pre, ok := c.Commands[sub]; ok && s == c {
switch h := action.Hand; sub { kit.Switch(sub,
case CTX_INIT: CTX_INIT, func() { merge(pre, true, key, cmd, action.Hand) },
merge(pre, true, key, cmd, h) CTX_EXIT, func() { merge(pre, false, key, cmd, action.Hand) },
case CTX_EXIT: )
merge(pre, false, key, cmd, h)
}
} }
if s == c { if s == c {
for _, h := range Info.merges { for _, h := range Info.merges {
@ -219,70 +168,37 @@ func (c *Context) Merge(s *Context) *Context {
if action.Hand == nil { if action.Hand == nil {
continue continue
} }
if action.List == nil { kit.If(action.List == nil, func() { action.List = SplitCmd(action.Name, nil) })
action.List = SplitCmd(action.Name, nil) kit.If(len(action.List) > 0, func() { cmd.Meta[sub] = action.List })
}
if len(action.List) > 0 {
cmd.Meta[sub] = action.List
} }
} }
} kit.If(c.Configs == nil, func() { c.Configs = Configs{} })
if c.Configs == nil {
c.Configs = Configs{}
}
for k, v := range s.Configs { for k, v := range s.Configs {
c.Configs[k] = v c.Configs[k] = v
} }
return c return c
} }
func (c *Context) Begin(m *Message, arg ...string) *Context { func (c *Context) Begin(m *Message, arg ...string) *Context {
follow := c.Name kit.If(c.Caches == nil, func() { c.Caches = Caches{} })
if c.context != nil && c.context != Index {
follow = kit.Keys(c.context.Cap(CTX_FOLLOW), c.Name)
}
if c.Caches == nil {
c.Caches = Caches{}
}
c.Caches[CTX_FOLLOW] = &Cache{Name: CTX_FOLLOW, Value: follow}
c.Caches[CTX_STATUS] = &Cache{Name: CTX_STATUS, Value: CTX_BEGIN}
c.Caches[CTX_STREAM] = &Cache{Name: CTX_STREAM, Value: ""} c.Caches[CTX_STREAM] = &Cache{Name: CTX_STREAM, Value: ""}
if c.Merge(c); c.server != nil { c.Caches[CTX_STATUS] = &Cache{Name: CTX_STATUS, Value: CTX_BEGIN}
c.server.Begin(m, arg...) c.Caches[CTX_FOLLOW] = &Cache{Name: CTX_FOLLOW, Value: c.Name}
} kit.If(c.context != nil && c.context != Index, func() { c.Cap(CTX_FOLLOW, kit.Keys(c.context.Cap(CTX_FOLLOW), c.Name)) })
return c kit.If(c.server != nil, func() { c.server.Begin(m, arg...) })
return c.Merge(c)
} }
func (c *Context) Start(m *Message, arg ...string) bool { func (c *Context) Start(m *Message, arg ...string) bool {
wait := make(chan bool, 1) m.Log(c.Cap(CTX_STATUS, CTX_START), c.Cap(CTX_FOLLOW))
defer func() { <-wait }() kit.If(c.server != nil, func() {
m.Go(func() { m.Go(func() { c.server.Start(m, arg...) }, m.Prefix())
wait <- true
m.Log(CTX_START, c.Cap(CTX_FOLLOW))
c.Cap(CTX_STATUS, CTX_START)
if c.server != nil {
c.server.Start(m, arg...)
}
}) })
return true return true
} }
func (c *Context) Close(m *Message, arg ...string) bool { func (c *Context) Close(m *Message, arg ...string) bool {
m.Log(CTX_CLOSE, c.Cap(CTX_FOLLOW)) m.Log(c.Cap(CTX_STATUS, CTX_CLOSE), c.Cap(CTX_FOLLOW))
c.Cap(CTX_STATUS, CTX_CLOSE) kit.If(c.server != nil, func() { c.server.Close(m, arg...) })
if c.server != nil {
return c.server.Close(m, arg...)
}
return true return true
} }
func (c *Context) Spawn(m *Message, name string, help string, arg ...string) *Context {
s := &Context{Name: name, Help: help}
if c.server != nil {
c.Register(s, c.server.Spawn(m, s, arg...))
} else {
c.Register(s, nil)
}
m.target = s
return s
}
type Message struct { type Message struct {
time time.Time time time.Time
@ -309,42 +225,42 @@ type Message struct {
I io.Reader I io.Reader
} }
func (m *Message) Time(args ...Any) string { func (m *Message) Time(arg ...Any) string {
t := m.time t := m.time
if len(args) > 0 { if len(arg) > 0 {
switch arg := args[0].(type) { switch arg := arg[0].(type) {
case string: case string:
if d, e := time.ParseDuration(arg); e == nil { if d, e := time.ParseDuration(arg); e == nil {
t, args = t.Add(d), args[1:] t, arg = t.Add(d), arg[1:]
} }
} }
} }
f := MOD_TIME f := MOD_TIME
if len(args) > 0 { if len(arg) > 0 {
switch arg := args[0].(type) { switch p := arg[0].(type) {
case string: case string:
if f = arg; len(args) > 1 { if f = p; len(arg) > 1 {
f = fmt.Sprintf(f, args[1:]...) f = fmt.Sprintf(f, arg[1:]...)
} }
} }
} }
return t.Format(f) return t.Format(f)
} }
func (m *Message) Target() *Context { func (m *Message) Target() *Context { return m.target }
return m.target func (m *Message) Source() *Context { return m.source }
func (m *Message) Message() *Message { return m.message }
func (m *Message) Commands(key string) *Command {
return m.Target().Commands[key]
} }
func (m *Message) Source() *Context { func (m *Message) Actions(key string) *Action {
return m.source return m._cmd.Actions[key]
}
func (m *Message) Message() *Message {
return m.message
} }
func (m *Message) Spawn(arg ...Any) *Message { func (m *Message) Spawn(arg ...Any) *Message {
msg := &Message{ msg := &Message{
time: time.Now(), code: int(m.target.root.ID()), time: time.Now(), code: int(m.target.root.ID()),
meta: map[string][]string{}, data: Map{}, meta: map[string][]string{}, data: Map{},
message: m, root: m.root, message: m, root: m.root, _target: logs.FileLine(2),
source: m.target, target: m.target, _cmd: m._cmd, _key: m._key, _sub: m._sub, _target: logs.FileLine(2), source: m.target, target: m.target, _cmd: m._cmd, _key: m._key, _sub: m._sub,
W: m.W, R: m.R, O: m.O, I: m.I, W: m.W, R: m.R, O: m.O, I: m.I,
} }
for _, val := range arg { for _, val := range arg {
@ -354,23 +270,19 @@ func (m *Message) Spawn(arg ...Any) *Message {
case Option: case Option:
msg.Option(val.Name, val.Value) msg.Option(val.Name, val.Value)
case Maps: case Maps:
for k, v := range val { kit.For(val, func(k, v string) { msg.Option(k, v) })
msg.Option(k, v)
}
case Map: case Map:
for k, v := range val { kit.For(val, func(k string, v Any) { msg.Option(k, v) })
msg.Option(k, v)
}
case http.ResponseWriter:
msg.W = val
case *http.Request:
msg.R = val
case *Context: case *Context:
msg.target = val msg.target = val
case *Command: case *Command:
msg._cmd = val msg._cmd = val
case string: case string:
msg._key = val msg._key = val
case http.ResponseWriter:
msg.W = val
case *http.Request:
msg.R = val
} }
} }
return msg return msg
@ -379,31 +291,23 @@ func (m *Message) Start(key string, arg ...string) *Message {
return m.Search(key+PT, func(p *Context, s *Context) { s.Start(m.Spawn(s), arg...) }) return m.Search(key+PT, func(p *Context, s *Context) { s.Start(m.Spawn(s), arg...) })
} }
func (m *Message) Travel(cb Any) *Message { func (m *Message) Travel(cb Any) *Message {
target := m.target
defer func() { m.target = target }()
list := []*Context{m.root.target} list := []*Context{m.root.target}
for i := 0; i < len(list); i++ { for i := 0; i < len(list); i++ {
switch cb := cb.(type) { switch cb := cb.(type) {
case func(*Context, *Context): case func(*Context, *Context):
cb(list[i].context, list[i]) cb(list[i].context, list[i])
case func(*Context, *Context, string, *Command): case func(*Context, *Context, string, *Command):
target := m.target
for _, k := range kit.SortedKey(list[i].Commands) {
m.target = list[i] m.target = list[i]
cb(list[i].context, list[i], k, list[i].Commands[k]) kit.For(kit.SortedKey(list[i].Commands), func(k string) { cb(list[i].context, list[i], k, list[i].Commands[k]) })
}
m.target = target
case func(*Context, *Context, string, *Config): case func(*Context, *Context, string, *Config):
target := m.target
for _, k := range kit.SortedKey(list[i].Configs) {
m.target = list[i] m.target = list[i]
cb(list[i].context, list[i], k, list[i].Configs[k]) kit.For(kit.SortedKey(list[i].Configs), func(k string) { cb(list[i].context, list[i], k, list[i].Configs[k]) })
}
m.target = target
default: default:
m.ErrorNotImplement(cb) m.ErrorNotImplement(cb)
} }
for _, k := range kit.SortedKey(list[i].Contexts) { kit.For(kit.SortedKey(list[i].Contexts), func(k string) { list = append(list, list[i].Contexts[k]) })
list = append(list, list[i].Contexts[k])
}
} }
return m return m
} }
@ -493,35 +397,13 @@ func (m *Message) Search(key string, cb Any) *Message {
return m return m
} }
func (m *Message) Commands(key string) *Command { func (m *Message) Cmd(arg ...Any) *Message { return m._command(arg...) }
return m.Target().Commands[key] func (m *Message) Cmds(arg ...Any) *Message { return m.Go(func() { m._command(arg...) }) }
}
func (m *Message) Actions(key string) *Action {
return m._cmd.Actions[key]
}
func (m *Message) CmdAppend(arg ...Any) string {
args := kit.Simple(arg...)
field := kit.Slice(args, -1)[0]
return m._command(kit.Slice(args, 0, -1), OptionFields(field)).Append(field)
}
func (m *Message) CmdMap(arg ...string) map[string]map[string]string {
field, list := kit.Slice(arg, -1)[0], map[string]map[string]string{}
m._command(kit.Slice(arg, 0, -1)).Tables(func(value Maps) { list[value[field]] = value })
return list
}
func (m *Message) Cmd(arg ...Any) *Message {
return m._command(arg...)
}
func (m *Message) Cmds(arg ...Any) *Message {
return m.Go(func() { m._command(arg...) })
}
func (m *Message) Cmdx(arg ...Any) string { func (m *Message) Cmdx(arg ...Any) string {
res := kit.Select("", m._command(arg...).meta[MSG_RESULT], 0) res := kit.Select("", m._command(arg...).meta[MSG_RESULT], 0)
return kit.Select("", res, res != ErrWarn) return kit.Select("", res, res != ErrWarn)
} }
func (m *Message) Cmdy(arg ...Any) *Message { func (m *Message) Cmdy(arg ...Any) *Message { return m.Copy(m._command(arg...)) }
return m.Copy(m._command(arg...))
}
func (m *Message) Confv(arg ...Any) (val Any) { func (m *Message) Confv(arg ...Any) (val Any) {
if m.Spawn().Warn(Info.Important && m.Option("_lock") == "") { if m.Spawn().Warn(Info.Important && m.Option("_lock") == "") {
m.Warn(true, "what unsafe lock", m.PrefixKey(), m.FormatStack(1, 100)) m.Warn(true, "what unsafe lock", m.PrefixKey(), m.FormatStack(1, 100))
@ -530,8 +412,7 @@ func (m *Message) Confv(arg ...Any) (val Any) {
if len(arg) == 1 { if len(arg) == 1 {
val = conf.Value val = conf.Value
return return
} } else if len(arg) > 2 {
if len(arg) > 2 {
if arg[1] == nil || arg[1] == "" { if arg[1] == nil || arg[1] == "" {
conf.Value = arg[2] conf.Value = arg[2]
} else { } else {
@ -541,9 +422,7 @@ func (m *Message) Confv(arg ...Any) (val Any) {
val = kit.Value(conf.Value, arg[1]) val = kit.Value(conf.Value, arg[1])
} }
key := kit.Format(arg[0]) key := kit.Format(arg[0])
if key == "" { kit.If(key == "", func() { key = m._key })
key = m._key
}
if conf, ok := m.target.Configs[key]; ok { if conf, ok := m.target.Configs[key]; ok {
run(conf) run(conf)
} else if conf, ok := m.source.Configs[key]; ok { } else if conf, ok := m.source.Configs[key]; ok {
@ -553,13 +432,9 @@ func (m *Message) Confv(arg ...Any) (val Any) {
} }
return return
} }
func (m *Message) Conf(arg ...Any) string { func (m *Message) Conf(arg ...Any) string { return kit.Format(m.Confv(arg...)) }
return kit.Format(m.Confv(arg...))
}
func (m *Message) Capi(key string, val ...Any) int { func (m *Message) Capi(key string, val ...Any) int {
if len(val) > 0 { kit.If(len(val) > 0, func() { m.Cap(key, kit.Int(m.Cap(key))+kit.Int(val[0])) })
m.Cap(key, kit.Int(m.Cap(key))+kit.Int(val[0]))
}
return kit.Int(m.Cap(key)) return kit.Int(m.Cap(key))
} }
func (m *Message) Capv(arg ...Any) Any { func (m *Message) Capv(arg ...Any) Any {
@ -571,15 +446,11 @@ func (m *Message) Capv(arg ...Any) Any {
for _, s := range []*Context{m.target} { for _, s := range []*Context{m.target} {
for c := s; c != nil; c = c.context { for c := s; c != nil; c = c.context {
if caps, ok := c.Caches[key]; ok { if caps, ok := c.Caches[key]; ok {
if len(arg) > 0 { kit.If(len(arg) > 0, func() { caps.Value = kit.Format(arg[0]) })
caps.Value = kit.Format(arg[0])
}
return caps.Value return caps.Value
} }
} }
} }
return nil return nil
} }
func (m *Message) Cap(arg ...Any) string { func (m *Message) Cap(arg ...Any) string { return kit.Format(m.Capv(arg...)) }
return kit.Format(m.Capv(arg...))
}