1
0
mirror of https://shylinux.com/x/icebergs synced 2025-06-26 10:27:31 +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
import ice "shylinux.com/x/icebergs"
import (
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/mdb"
)
const (
RSA = "rsa"
)
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 (
SEND = "send"
SUBJECT = "subject"
CONTENT = "content"
)
const EMAIL = "email"
@ -17,8 +19,6 @@ func init() {
const (
TO = "to"
ADMIN = "admin"
SUBJECT = "subject"
CONTENT = "content"
SERVICE = "service"
NL = "\r\n"
DF = ": "
@ -26,16 +26,14 @@ func init() {
Index.MergeCommands(ice.Commands{
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) {
if m.Option(SERVICE) == "" {
m.Options(m.Cmd("", ADMIN).AppendSimple(SERVICE, USERNAME, PASSWORD))
}
kit.If(m.Option(SERVICE) == "", func() { m.Options(m.Cmd("", ADMIN).AppendSimple(SERVICE, USERNAME, PASSWORD)) })
if m.Warn(m.Option(SERVICE) == "", ice.ErrNotValid, SERVICE) {
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))
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.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))},
})

View File

@ -2,6 +2,7 @@ package aaa
import (
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/gdb"
"shylinux.com/x/icebergs/base/mdb"
kit "shylinux.com/x/toolkits"
)
@ -15,30 +16,26 @@ const OFFER = "offer"
func init() {
Index.MergeCommands(ice.Commands{
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) {
h := mdb.HashCreate(m.Spawn(), m.OptionSimple(EMAIL, "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)),
kit.Dict(ice.MSG_USERNAME, m.Option(EMAIL), ice.MSG_USERNICK, VOID, ice.MSG_USERROLE, VOID))
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")))
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, SUBJECT, CONTENT), "from", m.Option(ice.MSG_USERNAME), mdb.STATUS, INVITE)
m.Cmd(EMAIL, SEND, m.Option(EMAIL), m.OptionDefault(SUBJECT, "welcome to contents, please continue"),
m.OptionDefault(CONTENT, ice.Render(m, ice.RENDER_ANCHOR, m.Cmdx("host", "publish", m.MergePodCmd("", "", mdb.HASH, h, gdb.DEBUG, ice.TRUE)))),
)
}},
ACCEPT: {Help: "接受", Hand: func(m *ice.Message, arg ...string) {
if m.Warn(m.Option(mdb.HASH) == "", ice.ErrNotValid, mdb.HASH) {
return
}
msg := m.Cmd("", m.Option(mdb.HASH))
ls := kit.Split(msg.Option(EMAIL), ice.AT)
m.Cmd(USER, mdb.CREATE, USERNAME, msg.Option(EMAIL), USERNICK, ls[0], USERZONE, ls[1])
m.ProcessOpen(kit.MergeURL2(m.Option(ice.MSG_USERWEB), ice.PS, ice.MSG_SESSID, SessCreate(m, msg.Option(EMAIL))))
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, 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.Append(EMAIL)), mdb.HASH, "", gdb.DEBUG, ice.TRUE))
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)
} else {
m.PushAction(ACCEPT)
}},
}, mdb.HashAction(mdb.SHORT, mdb.UNIQ, mdb.FIELD, "time,hash,status,from,email,title,content"), RoleAction(ACCEPT)), Hand: func(m *ice.Message, arg ...string) {
if !m.Warn(len(arg) == 0 && m.Option(ice.MSG_USERROLE) == VOID, ice.ErrNotRight) {
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 {
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) {
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 {
white, black := value[WHITE].(ice.Map), value[BLACK].(ice.Map)
for i := 0; i < len(key); i++ {
if v, o := white[kit.Join(key[:i+1], ice.PT)]; o && v == true {
ok = true
}
if v, o := black[kit.Join(key[:i+1], ice.PT)]; o && v == true {
ok = false
}
kit.If(white[kit.Join(key[:i+1], ice.PT)], func() { ok = true })
kit.If(black[kit.Join(key[:i+1], ice.PT)], func() { ok = false })
}
return ok
}
func _role_right(m *ice.Message, role string, key ...string) (ok bool) {
if role == ROOT {
return true
}
mdb.HashSelectDetail(m, kit.Select(VOID, role), func(value ice.Map) {
ok = _role_check(value, key, role == TECH)
})
return
return role == ROOT || len(mdb.HashSelectDetails(m, kit.Select(VOID, role), func(value ice.Map) bool { return _role_check(value, key, role == TECH) })) > 0
}
func _role_list(m *ice.Message, role string) *ice.Message {
mdb.HashSelectDetail(m, kit.Select(VOID, role), func(value ice.Map) {
kit.For(value[WHITE], func(k string, v ice.Any) {
m.Push(ROLE, kit.Value(value, mdb.NAME))
m.Push(mdb.ZONE, WHITE).Push(mdb.KEY, k).Push(mdb.STATUS, v)
m.Push(ROLE, kit.Value(value, mdb.NAME)).Push(mdb.ZONE, WHITE).Push(mdb.KEY, k).Push(mdb.STATUS, v)
})
kit.For(value[BLACK], func(k string, v ice.Any) {
m.Push(ROLE, kit.Value(value, mdb.NAME))
m.Push(mdb.ZONE, BLACK).Push(mdb.KEY, k).Push(mdb.STATUS, v)
m.Push(ROLE, kit.Value(value, mdb.NAME)).Push(mdb.ZONE, BLACK).Push(mdb.KEY, k).Push(mdb.STATUS, v)
})
})
return m.Sort(mdb.KEY).StatusTimeCount()
@ -69,7 +62,6 @@ const ROLE = "role"
func init() {
Index.MergeCommands(ice.Commands{
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) {
kit.For(arg, func(role string) {
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 {
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() {
m.Cmd(ROLE, WHITE, VOID, m.CommandKey())
m.Cmd(ROLE, BLACK, VOID, m.CommandKey(), ice.ACTION)
cmd = m.CommandKey()
}
m.Cmd(ROLE, WHITE, VOID, m.PrefixKey())
m.Cmd(ROLE, BLACK, VOID, m.PrefixKey(), ice.ACTION)
m.Cmd(ROLE, WHITE, VOID, strings.TrimPrefix(m.PrefixKey(), "web."))
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) })
m.Cmd(ROLE, WHITE, VOID, cmd)
m.Cmd(ROLE, BLACK, VOID, cmd, ice.ACTION)
kit.For(key, func(key string) { m.Cmd(ROLE, WHITE, VOID, cmd, ice.ACTION, key) })
}}}
}
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) })
}}}
}
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 {
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))

View File

@ -2,20 +2,17 @@ package aaa
import (
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/gdb"
"shylinux.com/x/icebergs/base/mdb"
kit "shylinux.com/x/toolkits"
"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 {
h = mdb.HashCreate(m, msg.AppendSimple(USERNICK, USERNAME, USERROLE), arg)
mdb.HashCreate(m, msg.AppendSimple(USERNICK, USERNAME, USERROLE), arg)
} 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) {
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 (
CHECK = "check"
GRANT = "grant"
LOGIN = "login"
LOGOUT = "logout"
SESSID = "sessid"
)
const (
SESS_CREATE = "sess.create"
)
const SESS = "sess"
@ -45,10 +37,8 @@ func init() {
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))
}},
CHECK: {Name: "check sessid*", Hand: func(m *ice.Message, arg ...string) {
_sess_check(m, m.Option(SESSID))
}},
}, mdb.HashAction(mdb.SHORT, mdb.UNIQ, mdb.FIELD, "time,hash,username,usernick,userrole,ua,ip", mdb.EXPIRE, mdb.MONTH, mdb.ImportantDataAction()))},
CHECK: {Name: "check sessid*", Hand: func(m *ice.Message, arg ...string) { _sess_check(m, m.Option(ice.MSG_SESSID)) }},
}, mdb.HashAction(mdb.EXPIRE, mdb.MONTH, mdb.SHORT, mdb.UNIQ, mdb.FIELD, "time,hash,usernick,username,userrole,ua,ip"), 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) {
if m.Option(ice.MSG_SESSID) == "" {
return
}
m.Cmd(SESS, mdb.REMOVE, kit.Dict(mdb.HASH, 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)) })
}

View File

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

View File

@ -1,21 +1,35 @@
package gdb
import (
"fmt"
"os"
"os/signal"
"syscall"
"time"
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/mdb"
kit "shylinux.com/x/toolkits"
"shylinux.com/x/toolkits/logs"
)
type Frame struct{ s chan os.Signal }
func (f *Frame) Begin(m *ice.Message, arg ...string) ice.Server {
f.s = make(chan os.Signal, 3)
return f
func (f *Frame) listen(m *ice.Message, s int, arg ...string) {
signal.Notify(f.s, syscall.Signal(s))
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)))
enable := mdb.Conf(m, TIMER, kit.Keym("enable")) == ice.TRUE
for {
@ -26,20 +40,13 @@ func (f *Frame) Start(m *ice.Message, arg ...string) bool {
}
case s, ok := <-f.s:
if !ok {
return true
return
}
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"

View File

@ -1,7 +1,6 @@
package gdb
import (
"fmt"
"os"
"os/signal"
"runtime"
@ -11,13 +10,11 @@ import (
"shylinux.com/x/icebergs/base/mdb"
kit "shylinux.com/x/toolkits"
"shylinux.com/x/toolkits/file"
"shylinux.com/x/toolkits/logs"
)
func _signal_listen(m *ice.Message, s int, arg ...string) {
if f, ok := m.Target().Server().(*Frame); ok {
signal.Notify(f.s, syscall.Signal(s))
mdb.HashCreate(m, SIGNAL, s, arg)
f.listen(m, s, arg...)
}
}
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, 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) {
_signal_listen(m, kit.Int(m.Option(SIGNAL)), arg...)

View File

@ -2,6 +2,7 @@ package log
import (
"bufio"
"fmt"
"path"
ice "shylinux.com/x/icebergs"
@ -12,7 +13,6 @@ import (
)
type Log struct {
m *ice.Message
p string
l string
s string
@ -20,56 +20,47 @@ type Log struct {
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)
ice.Info.Log = func(m *ice.Message, p, l, s string) { f.p <- &Log{m: m, p: p, l: l, s: s} }
return f
ice.Info.Log = func(m *ice.Message, p, l, s string) { f.p <- &Log{p: p, l: l, s: s} }
}
func (f *Frame) Start(m *ice.Message, arg ...string) bool {
func (f *Frame) Start(m *ice.Message, arg ...string) {
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 {
select {
case l, ok := <-f.p:
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 == "" {
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)
if bio == nil {
continue
return
}
bio.WriteString(l.p)
bio.WriteString(ice.SP)
if ice.Info.Colors == true {
if p, ok := view[PREFIX].(string); ok {
bio.WriteString(p)
}
}
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()
defer bio.Flush()
defer fmt.Fprintln(bio)
fmt.Fprint(bio, l.p, ice.SP)
view := mdb.Confm(m, VIEW, m.Conf(SHOW, kit.Keys(l.l, VIEW)))
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)
})
}
}
}
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
close(f.p)
return true
}
func (f *Frame) Spawn(m *ice.Message, c *ice.Context, arg ...string) ice.Server { return &Frame{} }
const (
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) {
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) })
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) {
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 {
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) }},
CREATE: {Hand: func(m *ice.Message, arg ...string) { HashCreate(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 {
HashSelectValue(m, func(value Map) {
if c, ok := value[TARGET].(io.Closer); ok {
c.Close()
m.Warn(c.Close())
}
delete(value, TARGET)
})

View File

@ -33,21 +33,11 @@ type Frame struct {
}
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
}
if m.Target().Cap(ice.CTX_STATUS) == ice.CTX_CLOSE {
return f
}
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")
}
kit.If(len(list) == 0, func() { list = append(list, f.ps1...) })
fmt.Fprintf(f.stdout, kit.Select("\r", "\r\033[2K", ice.Info.Colors))
for _, v := range list {
switch v {
case mdb.COUNT:
@ -59,9 +49,7 @@ func (f *Frame) prompt(m *ice.Message, list ...string) *Frame {
case TARGET:
fmt.Fprintf(f.stdout, f.target.Name)
default:
if ice.Info.Colors || v[0] != '\033' {
fmt.Fprintf(f.stdout, v)
}
kit.If(ice.Info.Colors || v[0] != '\033', func() { fmt.Fprintf(f.stdout, v) })
}
}
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)))
// m.Options(MESSAGE, m, ice.LOG_DISABLE, ice.TRUE)
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)
for f.prompt(m, ps...); f.stdin != nil && bio.Scan(); f.prompt(m, ps...) {
if len(bio.Text()) == 0 && h == STDIO {
@ -152,16 +143,15 @@ func (f *Frame) scan(m *ice.Message, h, line string) *Frame {
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] {
case "xterm", "screen":
ice.Info.Colors = true
default:
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)
switch f.source = kit.Select(STDIO, arg, 0); f.source {
case STDIO:
@ -185,7 +175,7 @@ func (f *Frame) Start(m *ice.Message, arg ...string) bool {
m.Option(ice.MSG_SCRIPT, f.source)
f.target = m.Source()
if msg := m.Cmd(nfs.CAT, f.source); msg.IsErr() {
return true
return
} else {
buf := bytes.NewBuffer(make([]byte, 0, ice.MOD_BUFS))
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, "", "")
}
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 {
stdin.Close()
}
f.stdin = nil
return true
}
func (f *Frame) Spawn(m *ice.Message, c *ice.Context, arg ...string) ice.Server {
return &Frame{}

View File

@ -6,8 +6,16 @@ import (
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/mdb"
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 {
m *ice.Message
h string
@ -26,7 +34,21 @@ func (l Listener) Close() error {
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) {
if m.Option("type") == "udp4" {
_server_udp(m, arg...)
return
}
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}
if e == nil {
@ -63,9 +85,7 @@ const SERVER = "server"
func init() {
Index.MergeCommands(ice.Commands{
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) {
_server_listen(m, arg...)
}},
LISTEN: {Name: "listen type name port=9030 host=", Hand: func(m *ice.Message, arg ...string) { _server_listen(m, arg...) }},
}, 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) {
if s, e := net.ListenUDP("udp4", _broad_addr(m, "0.0.0.0", port)); m.Assert(e) {
defer s.Close()
m.Go(func() {
m.Sleep("10ms").Cmd(tcp.HOST, func(values ice.Maps) {
m.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)
})
})
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)
for {
n, from, e := s.ReadFromUDP(buf[:])
n, from, e := l.ReadFromUDP(buf[:])
if e != nil {
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 {
m.Cmd(BROAD, func(value ice.Maps) {
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)
}
}
}
})
}
func _broad_save(m, msg *ice.Message) {
save := false
@ -101,6 +98,9 @@ func init() {
tcp.SEND: {Hand: func(m *ice.Message, arg ...string) {
_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())},
})
}

View File

@ -137,7 +137,7 @@ func init() {
cli.STOP: {Hand: func(m *ice.Message, arg ...string) {
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.Sleep("1s")
m.Sleep300ms()
}},
nfs.TRASH: {Hand: func(m *ice.Message, arg ...string) {
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/mdb"
"shylinux.com/x/icebergs/base/nfs"
"shylinux.com/x/icebergs/base/ssh"
"shylinux.com/x/icebergs/base/tcp"
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))
}
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(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)
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 {
const (
@ -192,27 +190,21 @@ func init() {
_serve_start(m)
}},
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.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() {
m.Go(func() {
opened := false
for i := 0; i < 3 && !opened; i++ {
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 })
})
}
if opened {
return
}
cli.Opens(m, _serve_address(m))
}()
kit.If(!opened, func() { cli.Opens(m, _serve_address(m)) })
})
}},
DOMAIN: {Hand: func(m *ice.Message, arg ...string) {
kit.If(len(arg) > 0, func() { ice.Info.Domain, ice.Info.Localhost = arg[0], false })
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) {
RenderIndex(m, arg...)
}},
@ -256,15 +248,6 @@ func init() {
}
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) {
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()) {
defer mdb.HashCreateDeferRemove(m, kit.SimpleKV("", MASTER, dev, msg.Append(tcp.HOSTNAME)), kit.Dict(mdb.TARGET, conn))()
if !prints && ice.Info.Colors {
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.Go(func() {
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
}
_space_handle(m.Spawn(), true, dev, conn)
@ -57,8 +57,8 @@ func _space_fork(m *ice.Message) {
case WORKER:
defer gdb.EventDeferEvent(m, DREAM_OPEN, args)(DREAM_CLOSE, args)
case CHROME:
m.Go(func() { m.Sleep30ms().Cmd(SPACE, name, cli.PWD, name) })
case aaa.LOGIN:
m.Cmd(SPACE, name, cli.PWD, name)
case LOGIN:
gdb.EventDeferEvent(m, SPACE_LOGIN, args)
}
_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) {
defer m.Cost(SPACE, name)
for {
_, b, e := conn.ReadMessage()
if e != nil {
m.Cost(SPACE, name, e)
break
}
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) {
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)
case SERVER:
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 {
@ -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.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)))
}},
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")
m.Tables(func(values ice.Maps) {
switch values[mdb.TYPE] {
case aaa.LOGIN:
m.PushButton(aaa.LOGIN, mdb.REMOVE)
case LOGIN:
m.PushButton(LOGIN, mdb.REMOVE)
default:
m.PushButton(cli.OPEN, mdb.REMOVE)
}

View File

@ -23,11 +23,10 @@ type Frame struct {
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{}
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}
list := map[*ice.Context]string{}
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)
}
})
gdb.EventDeferEvent(m, SERVE_START, arg)
switch cb := m.OptionCB("").(type) {
case func(http.Handler):
cb(f)
default:
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)()
gdb.EventDeferEvent(m, SERVE_START, arg)
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) {
if _serve_main(f.Message, 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) {
ctx.ProcessField(m, web.CODE_VIMER, func() []string {
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))
}
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) {
if web.IsNotValidShare(m, value[mdb.TIME]) {
return
@ -65,6 +69,7 @@ const HEADER = "header"
func init() {
Index.MergeCommands(ice.Commands{
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) {}},
aaa.LOGOUT: {Hand: aaa.SessLogout},
aaa.PASSWORD: {Hand: _header_users},
@ -74,14 +79,12 @@ func init() {
aaa.AVATAR: {Hand: _header_users},
web.SHARE: {Hand: _header_share},
"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...) {
return
}
msg := m.Cmd(aaa.USER, m.Option(ice.MSG_USERNAME))
for _, k := range []string{aaa.USERNICK, aaa.LANGUAGE} {
m.Option(k, msg.Append(k))
}
kit.For([]string{aaa.USERNICK, aaa.LANGUAGE}, func(k string) { m.Option(k, msg.Append(k)) })
for _, k := range []string{aaa.BACKGROUND, aaa.AVATAR} {
if strings.HasPrefix(msg.Append(k), ice.PS) || strings.HasPrefix(msg.Append(k), ice.HTTP) {
m.Option(k, msg.Append(k))

View File

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

View File

@ -52,7 +52,7 @@ func init() {
u := web.OptionUserWeb(m)
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.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) {
if mdb.ZoneSelect(m, arg...); len(arg) == 0 {

View File

@ -154,7 +154,7 @@ func init() {
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.Sleep("10ms").Cmd(UPGRADE, cli.RESTART) })
m.Go(func() { m.Sleep30ms().Cmd(UPGRADE, cli.RESTART) })
} else {
_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 cmd := text[0]; text[0] != "" {
m.Go(func() {
m.Sleep("10ms")
m.Sleep30ms()
tty.Write([]byte(cmd + ice.NL))
})
}

View File

@ -76,8 +76,9 @@ func (m *Message) TableGo(cb Any) *Message {
})
return m
}
func (m *Message) Go(cb Any) *Message {
task.Put(logs.FileLine(cb), func(task *task.Task) error {
func (m *Message) Go(cb Any, arg ...Any) *Message {
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) {
switch cb := cb.(type) {
case func(*Message):

69
init.go
View File

@ -13,7 +13,7 @@ import (
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}
m.Travel(func(p *Context, s *Context) {
s.root = m.target
@ -22,19 +22,14 @@ func (s *Frame) Begin(m *Message, arg ...string) Server {
s.Begin(list[s], arg...)
}
})
return s
}
func (s *Frame) Start(m *Message, arg ...string) bool {
m.Cap(CTX_STREAM, strings.Split(m.Time(), SP)[1])
func (s *Frame) Start(m *Message, arg ...string) {
m.Cmd(kit.Keys(MDB, CTX_INIT))
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)
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}
m.Travel(func(p *Context, s *Context) {
if msg, ok := list[p]; ok && msg != nil {
@ -43,26 +38,25 @@ func (s *Frame) Close(m *Message, arg ...string) bool {
}
})
conf.Close()
go func() { os.Exit(kit.Int(Pulse.Sleep("30ms").Option(EXIT))) }()
return true
go func() { os.Exit(kit.Int(Pulse.Sleep30ms().Option(EXIT))) }()
}
func (s *Frame) Spawn(m *Message, c *Context, arg ...string) Server { return &Frame{} }
const (
INIT = "init"
HELP = "help"
EXIT = "exit"
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) {
m.Travel(func(p *Context, c *Context) {
if p != nil {
c._command(m.Spawn(c), c.Commands[CTX_INIT], CTX_INIT, arg...)
}
kit.If(p != nil, func() { m.Go(func() { c._command(m.Spawn(c), c.Commands[CTX_INIT], CTX_INIT, arg...) }) })
})
loadImportant(m)
loadImportant(m)
loadImportant(m)
loadImportant(m)
loadImportant(m)
}},
INIT: {Hand: func(m *Message, arg ...string) {
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) {
defer m.Target().Close(m.Spawn(), arg...)
m.Travel(func(p *Context, c *Context) {
if p != nil {
c._command(m.Spawn(c), c.Commands[CTX_EXIT], CTX_EXIT, arg...)
}
kit.If(p != nil, func() { c._command(m.Spawn(c), c.Commands[CTX_EXIT], CTX_EXIT, arg...) })
})
removeImportant(m)
}},
}, 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 Run(arg ...string) string {
if len(arg) == 0 && len(os.Args) > 1 {
arg = kit.Simple(os.Args[1:], kit.Split(kit.Env(CTX_ARG)))
}
kit.If(len(arg) == 0 && len(os.Args) > 1, func() { arg = kit.Simple(os.Args[1:], kit.Split(kit.Env(CTX_ARG))) })
if len(arg) == 0 {
if runtime.GOOS == "windows" {
arg = append(arg, SERVE, START, DEV, DEV)
} else {
arg = append(arg, "pwd")
// arg = append(arg, "forever", START, DEV, DEV)
}
}
@ -105,32 +96,20 @@ func Run(arg ...string) string {
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)
if Pulse.time = time.Now(); Pulse._cmd == nil {
Pulse._cmd = &Command{RawHand: logs.FileLines(3)}
}
Pulse.time = time.Now()
switch Index.Merge(Index).Begin(Pulse, arg...); kit.Select("", arg, 0) {
case SERVE, SPACE:
if os.Getenv("ctx_log") == "" {
// os.Stderr.Close()
}
if Index.Start(Pulse, arg...) {
Index.Start(Pulse, arg...)
conf.Wait()
os.Exit(kit.Int(Pulse.Option(EXIT)))
}
default:
if logs.Disable(true); len(arg) == 0 {
arg = append(arg, HELP)
}
if Pulse.Cmdy(INIT).Cmdy(arg); Pulse.IsErrNotFound() {
Pulse.SetAppend().SetResult().Cmdy(SYSTEM, arg)
}
if strings.TrimSpace(Pulse.Result()) == "" && Pulse.Length() > 0 {
Pulse.Table()
}
if Pulse.Result() != "" && !strings.HasSuffix(Pulse.Result(), NL) {
Pulse.Echo(NL)
}
logs.Disable(true)
Pulse.Cmdy(INIT).Cmdy(arg)
kit.If(Pulse.IsErrNotFound(), func() { Pulse.SetAppend().SetResult().Cmdy(SYSTEM, arg) })
kit.If(strings.TrimSpace(Pulse.Result()) == "" && Pulse.Length() > 0, func() { Pulse.Table() })
kit.If(Pulse.Result() != "" && !strings.HasSuffix(Pulse.Result(), NL), func() { Pulse.Echo(NL) })
}
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)
}
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
hand := v.Hand
h.Hand = func(m *Message, arg ...string) {
hand(m, arg...)
last(m, arg...)
hand(m, arg...)
}
} else if h.Name = kit.Select(v.Name, h.Name); h.Hand == nil {
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) {
_status_each(m, "", cli.SYSTEM, GIT, PULL)
_status_each(m, "", cli.SYSTEM, GIT, PULL, "--tags")
m.Sleep("3s")
m.Sleep3s()
}},
PUSH: {Help: "上传", Hand: func(m *ice.Message, arg ...string) {
if m.Option(REPOS) == "" {
_status_each(m, "", cli.SYSTEM, GIT, PUSH)
_status_each(m, "", cli.SYSTEM, GIT, PUSH, "--tags")
m.Sleep("3s")
m.Sleep3s()
return
}
m.Option(cli.CMD_DIR, _repos_path(m.Option(REPOS)))

View File

@ -117,7 +117,7 @@ func init() {
return
}
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, "1"), "vi etc/miss.sh", ENTER)
})

View File

@ -126,6 +126,19 @@ func (m *Message) IsCliUA() bool {
func (m *Message) IsMobileUA() bool {
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) {
data := kit.Dict(arg...)
for i := 0; i < len(arg); i += 2 {

299
type.go
View File

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