From e516bf6ec8accbe79570ac9f68bd1bea0845d51d Mon Sep 17 00:00:00 2001 From: harveyshao Date: Wed, 3 Aug 2022 08:14:22 +0800 Subject: [PATCH] opt base --- base/aaa/aaa.go | 11 +- base/aaa/role.go | 13 +-- base/aaa/sess.go | 24 ++-- base/aaa/totp.go | 2 +- base/aaa/user.go | 56 +++++---- base/cli/cli.shy | 1 + base/cli/daemon.go | 21 ++-- base/cli/forever.go | 10 +- base/cli/mirrors.go | 36 +++--- base/cli/runtime.go | 13 ++- base/cli/system.go | 19 +--- base/ctx/command.go | 72 +++++++++++- base/ctx/config.go | 30 ++++- base/ctx/context.go | 3 +- base/ctx/option.go | 60 ++++++++++ base/gdb/event.go | 9 ++ base/gdb/gdb.go | 6 +- base/gdb/routine.go | 10 +- base/gdb/signal.go | 17 ++- base/gdb/timer.go | 2 +- base/lex/matrix.go | 27 +++-- base/lex/split.go | 2 +- base/log/log.go | 26 ++--- base/mdb/hash.go | 183 +++++++++++++++--------------- base/mdb/list.go | 109 +++++++++++++----- base/mdb/mdb.go | 116 ++++++++++++------- base/mdb/render.go | 2 +- base/mdb/search.go | 29 +++++ base/mdb/zone.go | 100 +++++++--------- base/nfs/cat.go | 44 ++++--- base/nfs/dir.go | 14 +-- base/nfs/nfs.go | 102 +---------------- base/nfs/pack.go | 114 ++++++++++++++++++- base/nfs/save.go | 13 ++- base/nfs/tail.go | 10 +- base/nfs/tar.go | 2 - base/nfs/trash.go | 2 +- base/ssh/render.go | 31 +++++ base/ssh/scripts.go | 39 +------ base/ssh/ssh.shy | 10 +- base/tcp/client.go | 26 +---- base/tcp/host.go | 14 +-- base/tcp/port.go | 2 +- base/tcp/server.go | 51 ++------- base/tcp/tcp.shy | 8 +- base/web/broad.go | 21 ++-- base/web/cache.go | 21 +++- base/web/dream.go | 55 ++++----- base/web/option.go | 132 +++++++++++++++++++++ base/web/render.go | 102 +++++++++++------ base/web/route.go | 8 +- base/web/serve.go | 101 ++++++++--------- base/web/share.go | 33 +++--- base/web/space.go | 113 ++++++++++-------- base/web/spide.go | 54 +++++---- base/web/web.go | 25 ++-- base/yac/matrix.go | 18 +-- conf.go | 179 ++++++++--------------------- core/chat/action.go | 54 ++------- core/chat/cmd.go | 22 ++-- core/chat/div.go | 11 +- core/chat/header.go | 2 +- core/chat/location.go | 2 +- core/chat/node.go | 7 +- core/chat/oauth/oauth.go | 13 ++- core/chat/pod.go | 8 +- core/chat/river.go | 8 +- core/chat/search.go | 2 +- core/chat/sso.go | 2 +- core/chat/storm.go | 7 +- core/chat/topic.go | 2 +- core/chat/trans.go | 9 +- core/chat/website.go | 27 ++--- core/code/autogen.go | 2 +- core/code/binpack.go | 19 ---- core/code/compile.go | 9 +- core/code/favor.go | 3 +- core/code/go.go | 11 +- core/code/inner.go | 7 +- core/code/install.go | 14 +-- core/code/js.go | 19 +++- core/code/oauth.go | 6 +- core/code/pprof.go | 2 +- core/code/publish.go | 11 +- core/code/py.go | 8 +- core/code/sh.go | 7 +- core/code/shy.go | 2 +- core/code/upgrade.go | 6 +- core/code/vimer.go | 12 +- core/code/webpack.go | 3 +- core/code/xterm.go | 10 +- core/code/zml.go | 3 +- core/mall/asset.go | 3 +- core/team/epic.go | 4 +- core/team/plan.go | 10 +- core/team/todo.go | 3 +- core/wiki/chart.go | 4 +- core/wiki/data.go | 24 +++- core/wiki/field.go | 3 +- core/wiki/spark.go | 12 +- core/wiki/wiki.go | 34 +++++- core/wiki/word.go | 5 +- data.go | 109 ------------------ exec.go | 84 +------------- info.go | 95 +--------------- init.go | 23 ++-- lock.go | 36 ------ logs.go | 212 +++++++++++++--------------------- meta.go | 62 ++++++---- misc.go | 147 ++++++++++-------------- misc/alpha/alpha.go | 5 +- misc/bash/favor.go | 5 +- misc/bash/input.go | 5 +- misc/bash/run.go | 3 +- misc/bash/sync.go | 7 +- misc/bash/trash.go | 7 +- misc/chrome/cache.go | 2 +- misc/chrome/sync.go | 3 +- misc/chrome/video.go | 3 +- misc/git/git.go | 2 +- misc/git/repos.go | 2 +- misc/git/server.go | 20 ++-- misc/git/spide.go | 2 +- misc/git/status.go | 21 ++-- misc/git/total.go | 18 ++- misc/input/input.go | 14 +-- misc/lark/sso.go | 4 +- misc/lark/talk.go | 4 +- misc/tmux/buffer.go | 6 +- misc/vim/favor.go | 3 +- misc/vim/sync.go | 5 +- misc/vim/tags.go | 3 +- misc/wx/login.go | 2 +- option.go | 239 +++++++++------------------------------ render.go | 230 ++++++++++--------------------------- type.go | 80 ++++++------- 136 files changed, 1993 insertions(+), 2255 deletions(-) create mode 100644 base/ctx/option.go create mode 100644 base/ssh/render.go create mode 100644 base/web/option.go delete mode 100644 lock.go diff --git a/base/aaa/aaa.go b/base/aaa/aaa.go index b4b62308..9fd1f35c 100644 --- a/base/aaa/aaa.go +++ b/base/aaa/aaa.go @@ -1,6 +1,10 @@ package aaa -import ice "shylinux.com/x/icebergs" +import ( + ice "shylinux.com/x/icebergs" + kit "shylinux.com/x/toolkits" + "shylinux.com/x/toolkits/logs" +) const ( RSA = "rsa" @@ -10,3 +14,8 @@ const AAA = "aaa" var Index = &ice.Context{Name: AAA, Help: "认证模块"} func init() { ice.Index.Register(Index, nil, ROLE, SESS, TOTP, USER, RSA) } + +func Right(m *ice.Message, arg ...ice.Any) bool { + return m.Option(ice.MSG_USERROLE) == ROOT || !m.Warn(m.Cmdx(ROLE, RIGHT, m.Option(ice.MSG_USERROLE), arg) != ice.OK, + ice.ErrNotRight, kit.Join(kit.Simple(arg), ice.PT), USERROLE, m.Option(ice.MSG_USERROLE), logs.FileLineMeta(kit.FileLine(2, 3))) +} diff --git a/base/aaa/role.go b/base/aaa/role.go index 6c13f06b..8cd38baa 100644 --- a/base/aaa/role.go +++ b/base/aaa/role.go @@ -15,14 +15,14 @@ func _role_chain(arg ...string) string { } func _role_black(m *ice.Message, userrole, chain string) { mdb.HashSelectUpdate(m, userrole, func(value ice.Map) { - m.Log_INSERT(ROLE, userrole, BLACK, chain) + m.Logs(mdb.INSERT, ROLE, userrole, BLACK, chain) list := value[BLACK].(ice.Map) list[chain] = true }) } func _role_white(m *ice.Message, userrole, chain string) { mdb.HashSelectUpdate(m, userrole, func(value ice.Map) { - m.Log_INSERT(ROLE, userrole, WHITE, chain) + m.Logs(mdb.INSERT, ROLE, userrole, WHITE, chain) list := value[WHITE].(ice.Map) list[chain] = true }) @@ -95,8 +95,8 @@ func init() { Index.MergeCommands(ice.Commands{ ROLE: {Name: "role role auto insert", Help: "角色", Actions: ice.MergeAction(ice.Actions{ ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { - m.Rich(ROLE, nil, kit.Dict(mdb.NAME, TECH, BLACK, kit.Dict(), WHITE, kit.Dict())) - m.Rich(ROLE, nil, kit.Dict(mdb.NAME, VOID, WHITE, kit.Dict(), BLACK, kit.Dict())) + mdb.Rich(m, ROLE, nil, kit.Dict(mdb.NAME, TECH, BLACK, kit.Dict(), WHITE, kit.Dict())) + mdb.Rich(m, ROLE, nil, kit.Dict(mdb.NAME, VOID, WHITE, kit.Dict(), BLACK, kit.Dict())) m.Cmd(ROLE, WHITE, VOID, ice.SRC) m.Cmd(ROLE, WHITE, VOID, ice.BIN) m.Cmd(ROLE, WHITE, VOID, ice.USR) @@ -105,19 +105,18 @@ func init() { }}, mdb.INSERT: {Name: "insert role=void,tech zone=white,black key=", Help: "添加", Hand: func(m *ice.Message, arg ...string) { mdb.HashSelectUpdate(m, m.Option(ROLE), func(key string, value ice.Map) { - m.Log_INSERT(ROLE, m.Option(ROLE), m.Option(mdb.ZONE), m.Option(mdb.KEY)) + m.Logs(mdb.INSERT, ROLE, m.Option(ROLE), m.Option(mdb.ZONE), m.Option(mdb.KEY)) list := value[m.Option(mdb.ZONE)].(ice.Map) list[_role_chain(m.Option(mdb.KEY))] = true }) }}, mdb.DELETE: {Name: "delete", Help: "删除", Hand: func(m *ice.Message, arg ...string) { mdb.HashSelectUpdate(m, m.Option(ROLE), func(key string, value ice.Map) { - m.Log_DELETE(ROLE, m.Option(ROLE), m.Option(mdb.ZONE), m.Option(mdb.KEY)) + m.Logs(mdb.DELETE, ROLE, m.Option(ROLE), m.Option(mdb.ZONE), m.Option(mdb.KEY)) list := value[m.Option(mdb.ZONE)].(ice.Map) delete(list, _role_chain(m.Option(mdb.KEY))) }) }}, - BLACK: {Name: "black role chain", Help: "黑名单", Hand: func(m *ice.Message, arg ...string) { _role_black(m, arg[0], _role_chain(arg[1:]...)) }}, diff --git a/base/aaa/sess.go b/base/aaa/sess.go index bc6bc866..239bf8ae 100644 --- a/base/aaa/sess.go +++ b/base/aaa/sess.go @@ -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" "shylinux.com/x/toolkits/logs" @@ -11,7 +12,7 @@ func _sess_check(m *ice.Message, sessid string) { m.Option(ice.MSG_USERROLE, VOID) m.Option(ice.MSG_USERNAME, "") m.Option(ice.MSG_USERNICK, "") - if sessid == "" { + if m.Warn(sessid == "", ice.ErrNotValid, sessid) { return } @@ -20,7 +21,7 @@ func _sess_check(m *ice.Message, sessid string) { if m.Warn(kit.Time(kit.Format(value[mdb.TIME])) < kit.Time(m.Time()), ice.ErrNotValid, sessid) { return // 会话超时 } - m.Log_AUTH( + m.Logs(ice.LOG_AUTH, USERROLE, m.Option(ice.MSG_USERROLE, value[USERROLE]), USERNAME, m.Option(ice.MSG_USERNAME, value[USERNAME]), USERNICK, m.Option(ice.MSG_USERNICK, value[USERNICK]), @@ -28,20 +29,17 @@ func _sess_check(m *ice.Message, sessid string) { ) }) } -func _sess_create(m *ice.Message, username string) string { - if username == "" { - return "" +func _sess_create(m *ice.Message, username string) (h string) { + if m.Warn(username == "", ice.ErrNotValid, username) { + return } - msg := m.Cmd(USER, username) - if msg.Length() > 0 { - h := mdb.HashCreate(m, msg.AppendSimple(USERROLE, USERNAME, USERNICK), IP, m.Option(ice.MSG_USERIP), UA, m.Option(ice.MSG_USERUA)).Result() - m.Event(SESS_CREATE, SESS, h, USERNAME, username) - return h + if msg := m.Cmd(USER, username); msg.Length() > 0 { + h = mdb.HashCreate(m, msg.AppendSimple(USERROLE, USERNAME, USERNICK), IP, m.Option(ice.MSG_USERIP), UA, m.Option(ice.MSG_USERUA)).Result() } else { - h := mdb.HashCreate(m, m.OptionSimple(USERROLE, USERNAME, USERNICK), IP, m.Option(ice.MSG_USERIP), UA, m.Option(ice.MSG_USERUA)).Result() - m.Event(SESS_CREATE, SESS, h, USERNAME, username) - return h + h = mdb.HashCreate(m, m.OptionSimple(USERROLE, USERNAME, USERNICK), IP, m.Option(ice.MSG_USERIP), UA, m.Option(ice.MSG_USERUA)).Result() } + gdb.Event(m, SESS_CREATE, SESS, h, USERNAME, username) + return h } const ( diff --git a/base/aaa/totp.go b/base/aaa/totp.go index 429ce8cf..b82ab344 100644 --- a/base/aaa/totp.go +++ b/base/aaa/totp.go @@ -64,7 +64,7 @@ func init() { }, mdb.HashAction(mdb.SHORT, mdb.NAME, mdb.FIELD, "time,name,secret,period,number", mdb.LINK, "otpauth://totp/%s?secret=%s")), Hand: func(m *ice.Message, arg ...string) { mdb.HashSelect(m.Spawn(), arg...).Tables(func(value ice.Maps) { if len(arg) > 0 { - m.OptionFields(mdb.DETAIL) + m.OptionFields(ice.FIELDS_DETAIL) } m.Push(mdb.TIME, m.Time()) m.Push(mdb.NAME, value[mdb.NAME]) diff --git a/base/aaa/user.go b/base/aaa/user.go index 5350d5c4..16c38b3c 100644 --- a/base/aaa/user.go +++ b/base/aaa/user.go @@ -2,11 +2,25 @@ 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 _user_create(m *ice.Message, name, word string, arg ...string) { + if m.Warn(name == "", ice.ErrNotValid, name) { + return + } + if word == "" { + word = m.CmdAppend(USER, name, PASSWORD) + } + if word == "" { + word = kit.Hashs() + } + mdb.HashCreate(m, USERNAME, name, PASSWORD, word, arg) + gdb.Event(m, USER_CREATE, USER, name) +} func _user_login(m *ice.Message, name, word string) { if m.Warn(name == "", ice.ErrNotValid, name) { return @@ -20,7 +34,7 @@ func _user_login(m *ice.Message, name, word string) { if m.Warn(word != "" && word != kit.Format(kit.Value(value, kit.Keys(mdb.EXTRA, PASSWORD))), ice.ErrNotRight) { return } - m.Log_AUTH( + m.Logs(ice.LOG_AUTH, USERROLE, m.Option(ice.MSG_USERROLE, value[USERROLE]), USERNAME, m.Option(ice.MSG_USERNAME, value[USERNAME]), USERNICK, m.Option(ice.MSG_USERNICK, value[USERNICK]), @@ -28,19 +42,6 @@ func _user_login(m *ice.Message, name, word string) { ) }) } -func _user_create(m *ice.Message, name, word string, arg ...string) { - if m.Warn(name == "", ice.ErrNotValid, name) { - return - } - if word == "" { - word = m.CmdAppend(USER, name, PASSWORD) - } - if word == "" { - word = kit.Hashs() - } - mdb.HashCreate(m, USERNAME, name, PASSWORD, word, arg) - m.Event(USER_CREATE, USER, name) -} const ( BACKGROUND = "background" @@ -61,11 +62,9 @@ const ( PASSWORD = "password" USERNICK = "usernick" USERZONE = "userzone" -) -const ( + USER_CREATE = "user.create" -) -const ( + INVITE = "invite" ) const USER = "user" @@ -73,16 +72,13 @@ const USER = "user" func init() { Index.MergeCommands(ice.Commands{ USER: {Name: "user username auto create", Help: "用户", Actions: ice.MergeAction(ice.Actions{ - mdb.SEARCH: {Name: "search type name text", Help: "搜索", Hand: func(m *ice.Message, arg ...string) { - mdb.HashSelectSearch(m, arg) - }}, mdb.CREATE: {Name: "create username password userrole=void,tech", Help: "创建", Hand: func(m *ice.Message, arg ...string) { _user_create(m, m.Option(USERNAME), m.Option(PASSWORD), m.OptionSimple(USERROLE)...) }}, LOGIN: {Name: "login username password", Help: "登录", Hand: func(m *ice.Message, arg ...string) { _user_login(m, m.Option(USERNAME), m.Option(PASSWORD)) }}, - }, mdb.HashAction(mdb.SHORT, USERNAME, mdb.FIELD, "time,userrole,username,usernick,userzone"))}, + }, mdb.HashSearchAction(mdb.SHORT, USERNAME, mdb.FIELD, "time,userrole,username,usernick,userzone"))}, }) } @@ -95,6 +91,14 @@ func UserRoot(m *ice.Message, arg ...string) *ice.Message { // password username } return m } +func UserInfo(m *ice.Message, name ice.Any, key, meta string) (value string) { + if m.Cmd(USER, name).Tables(func(val ice.Maps) { + value = val[key] + }).Length() == 0 && kit.Format(name) == m.Option(ice.MSG_USERNAME) { + return m.Option(meta) + } + return +} func UserRole(m *ice.Message, username ice.Any) (role string) { if role = VOID; username == ice.Info.UserName { return ROOT @@ -107,14 +111,6 @@ func UserNick(m *ice.Message, username ice.Any) (nick string) { func UserZone(m *ice.Message, username ice.Any) (zone string) { return UserInfo(m, username, USERZONE, ice.MSG_USERZONE) } -func UserInfo(m *ice.Message, name ice.Any, key, meta string) (value string) { - if m.Cmd(USER, name).Tables(func(val ice.Maps) { - value = val[key] - }).Length() == 0 && kit.Format(name) == m.Option(ice.MSG_USERNAME) { - return m.Option(meta) - } - return -} func UserLogin(m *ice.Message, username, password string) bool { return m.Cmdy(USER, LOGIN, username, password).Option(ice.MSG_USERNAME) != "" } diff --git a/base/cli/cli.shy b/base/cli/cli.shy index 4627ac49..8a9b32ab 100644 --- a/base/cli/cli.shy +++ b/base/cli/cli.shy @@ -5,4 +5,5 @@ field "扫码" qrcode field "命令" system field "守护" daemon field "启动" forever +field "镜像" mirrors diff --git a/base/cli/daemon.go b/base/cli/daemon.go index e35776e2..df180798 100644 --- a/base/cli/daemon.go +++ b/base/cli/daemon.go @@ -8,6 +8,7 @@ import ( "shylinux.com/x/icebergs/base/ctx" "shylinux.com/x/icebergs/base/gdb" "shylinux.com/x/icebergs/base/mdb" + "shylinux.com/x/icebergs/base/nfs" kit "shylinux.com/x/toolkits" ) @@ -22,10 +23,9 @@ func _daemon_exec(m *ice.Message, cmd *exec.Cmd) { cmd.Stderr = w } - h := mdb.HashCreate(m, - STATUS, START, ice.CMD, kit.Join(cmd.Args, ice.SP), - DIR, cmd.Dir, ENV, kit.Select("", cmd.Env), - m.OptionSimple(CMD_OUTPUT, CMD_ERRPUT, mdb.CACHE_CLEAR_ON_EXIT), + h := mdb.HashCreate(m, ice.CMD, kit.Join(cmd.Args, ice.SP), + STATUS, START, DIR, cmd.Dir, ENV, kit.Select("", cmd.Env), + m.OptionSimple(CMD_INPUT, CMD_OUTPUT, CMD_ERRPUT, mdb.CACHE_CLEAR_ON_EXIT), ).Result() // 启动服务 @@ -48,8 +48,8 @@ func _daemon_exec(m *ice.Message, cmd *exec.Cmd) { }) } - status := mdb.HashSelectFields(m, h, STATUS) - switch m.Sleep300ms(); cb := m.OptionCB(DAEMON).(type) { + status := mdb.HashSelectField(m, h, STATUS) + switch m.Sleep300ms(); cb := m.OptionCB("").(type) { case func(string) bool: if !cb(status) { // 拉起服务 m.Cmdy(DAEMON, cmd.Path, cmd.Args) @@ -62,9 +62,8 @@ func _daemon_exec(m *ice.Message, cmd *exec.Cmd) { default: m.ErrorNotImplement(cb) } - for _, p := range kit.Simple(CMD_INPUT, CMD_OUTPUT, CMD_ERRPUT) { - kit.Close(m.Optionv(p)) + nfs.CloseFile(m, m.Optionv(p)) } }) } @@ -113,10 +112,6 @@ func init() { ice.CTX_EXIT: {Hand: func(m *ice.Message, arg ...string) { mdb.HashPrunesValue(m, mdb.CACHE_CLEAR_ON_EXIT, ice.TRUE) }}, - mdb.PRUNES: {Name: "prunes", Help: "清理", Hand: func(m *ice.Message, arg ...string) { - mdb.HashPrunesValue(m, STATUS, ERROR) - mdb.HashPrunesValue(m, STATUS, STOP) - }}, START: {Name: "start cmd env dir", Help: "添加", Hand: func(m *ice.Message, arg ...string) { m.Option(CMD_DIR, m.Option(DIR)) m.Option(CMD_ENV, kit.Split(m.Option(ENV), " =")) @@ -132,7 +127,7 @@ func init() { m.Cmd(gdb.SIGNAL, gdb.KILL, value[PID]) }) }}, - }, mdb.HashAction(mdb.FIELD, "time,hash,status,pid,cmd,dir,env")), Hand: func(m *ice.Message, arg ...string) { + }, mdb.HashStatusAction(mdb.FIELD, "time,hash,status,pid,cmd,dir,env")), Hand: func(m *ice.Message, arg ...string) { if mdb.HashSelect(m, arg...).Tables(func(value ice.Maps) { switch value[STATUS] { case START: diff --git a/base/cli/forever.go b/base/cli/forever.go index 2b81707d..c2317d05 100644 --- a/base/cli/forever.go +++ b/base/cli/forever.go @@ -20,7 +20,7 @@ const FOREVER = "forever" func init() { Index.MergeCommands(ice.Commands{ FOREVER: {Name: "forever auto", Help: "启动", Actions: ice.Actions{ - gdb.START: {Name: "start", Help: "服务", Hand: func(m *ice.Message, arg ...string) { + START: {Name: "start", Help: "服务", Hand: func(m *ice.Message, arg ...string) { env := []string{PATH, BinPath(), HOME, kit.Select(kit.Path(""), os.Getenv(HOME))} for _, k := range ENV_LIST { if kit.Env(k) != "" { @@ -40,10 +40,10 @@ func init() { m.Cmdy(FOREVER, kit.Select(os.Args[0], nfs.PWD+ice.BIN_ICE_BIN, kit.FileExists(ice.BIN_ICE_BIN)), "serve", START, ice.DEV, "", aaa.USERNAME, aaa.ROOT, aaa.PASSWORD, aaa.ROOT, arg) }}, - gdb.RESTART: {Name: "restart", Help: "重启", Hand: func(m *ice.Message, arg ...string) { + RESTART: {Name: "restart", Help: "重启", Hand: func(m *ice.Message, arg ...string) { m.Cmd(gdb.SIGNAL, gdb.RESTART) }}, - gdb.STOP: {Name: "stop", Help: "停止", Hand: func(m *ice.Message, arg ...string) { + STOP: {Name: "stop", Help: "停止", Hand: func(m *ice.Message, arg ...string) { m.Cmd(gdb.SIGNAL, gdb.STOP) }}, }, Hand: func(m *ice.Message, arg ...string) { @@ -54,8 +54,8 @@ func init() { for { logs.Println("run %s", kit.Join(arg, ice.SP)) - if m.Sleep("100ms"); IsSuccess(m.Cmd(SYSTEM, arg)) { - logs.Println("exit") + if m.Sleep300ms(); IsSuccess(m.Cmd(SYSTEM, arg)) { + logs.Println(ice.EXIT) break } } diff --git a/base/cli/mirrors.go b/base/cli/mirrors.go index cf4ed3ab..844c7887 100644 --- a/base/cli/mirrors.go +++ b/base/cli/mirrors.go @@ -23,23 +23,27 @@ func init() { Index.MergeCommands(ice.Commands{ MIRRORS: {Name: "mirrors cli auto", Help: "软件镜像", Actions: ice.MergeAction(ice.Actions{ ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { - m.Conf(m.PrefixKey(), kit.Keys(mdb.HASH), "") - IsAlpine(m, "curl") - IsAlpine(m, "make") - IsAlpine(m, "gcc") - IsAlpine(m, "vim") - IsAlpine(m, "tmux") + m.Go(func() { + m.Sleep300ms() // after runtime init + m.Conf(m.Prefix(MIRRORS), kit.Keys(mdb.HASH), "") + IsAlpine(m, "curl") + IsAlpine(m, "make") + IsAlpine(m, "gcc") + IsAlpine(m, "vim") + IsAlpine(m, "tmux") - IsAlpine(m, "git") - mdb.ZoneInsert(m, CLI, "go", CMD, kit.Format("install download https://golang.google.cn/dl/go1.15.5.%s-%s.tar.gz usr/local", runtime.GOOS, runtime.GOARCH)) + if IsAlpine(m, "git"); !IsAlpine(m, "go", "go git") { + mdb.ZoneInsert(m, CLI, "go", CMD, kit.Format("install download https://golang.google.cn/dl/go1.15.5.%s-%s.tar.gz usr/local", runtime.GOOS, runtime.GOARCH)) + } - IsAlpine(m, "node", "nodejs") - IsAlpine(m, "java", "openjdk8") - IsAlpine(m, "javac", "openjdk8") - IsAlpine(m, "mvn", "openjdk8 maven") - IsAlpine(m, "python", "python2") - IsAlpine(m, "python2") - IsAlpine(m, "python3") + IsAlpine(m, "node", "nodejs") + IsAlpine(m, "java", "openjdk8") + IsAlpine(m, "javac", "openjdk8") + IsAlpine(m, "mvn", "maven openjdk8") + IsAlpine(m, "python", "python2") + IsAlpine(m, "python2") + IsAlpine(m, "python3") + }) }}, mdb.INSERT: {Name: "insert cli osid cmd", Help: "添加"}, CMD: {Name: "cmd cli osid", Help: "安装", Hand: func(m *ice.Message, arg ...string) { @@ -60,7 +64,7 @@ func init() { func IsAlpine(m *ice.Message, arg ...string) bool { if strings.Contains(m.Conf(RUNTIME, kit.Keys(HOST, OSID)), ALPINE) { if len(arg) > 0 { - mdb.ZoneInsert(m, CLI, arg[0], OSID, ALPINE, CMD, "system apk add "+kit.Select(arg[0], arg, 1)) + m.Cmd(mdb.INSERT, m.Prefix(MIRRORS), "", mdb.ZONE, arg[0], OSID, ALPINE, CMD, "system apk add "+kit.Select(arg[0], arg, 1)) } return true } diff --git a/base/cli/runtime.go b/base/cli/runtime.go index 6eefdc6c..9b183f1c 100644 --- a/base/cli/runtime.go +++ b/base/cli/runtime.go @@ -78,6 +78,14 @@ func _runtime_init(m *ice.Message) { } }) m.Conf(RUNTIME, kit.Keys(HOST, OSID), osid) + + switch strings.Split(os.Getenv(TERM), "-")[0] { + case "xterm", "screen": + ice.Info.Colors = true + default: + ice.Info.Colors = false + } + } func _runtime_hostinfo(m *ice.Message) { m.Push("nCPU", strings.Count(m.Cmdx(nfs.CAT, "/proc/cpuinfo"), "processor")) @@ -96,7 +104,7 @@ func _runtime_diskinfo(m *ice.Message) { } }) m.RenameAppend("%iused", "piused", "Use%", "Usep") - m.DisplayStory("pie.js?field=Size") + ctx.DisplayStory(m, "pie.js?field=Size") } func NodeInfo(m *ice.Message, kind, name string) { @@ -250,7 +258,8 @@ func init() { if len(arg) > 0 && arg[0] == BOOTINFO { arg = arg[1:] } - m.Cmdy(ctx.CONFIG, RUNTIME, arg).DisplayStoryJSON() + m.Cmdy(ctx.CONFIG, RUNTIME, arg) + ctx.DisplayStoryJSON(m) }}, }) } diff --git a/base/cli/system.go b/base/cli/system.go index 1addc0c8..94fa491c 100644 --- a/base/cli/system.go +++ b/base/cli/system.go @@ -18,7 +18,7 @@ import ( func _system_cmd(m *ice.Message, arg ...string) *exec.Cmd { if text := kit.ReadFile(ice.ETC_PATH); len(text) > 0 { if file := _system_find(m, arg[0], strings.Split(text, ice.NL)...); file != "" { - m.Log_SELECT("etc path cmd", file) + m.Logs(mdb.SELECT, "etc path cmd", file) arg[0] = file // 配置目录 } } @@ -26,7 +26,7 @@ func _system_cmd(m *ice.Message, arg ...string) *exec.Cmd { for i := 0; i < len(env)-1; i += 2 { if env[i] == PATH { if file := _system_find(m, arg[0], strings.Split(env[i+1], ice.DF)...); file != "" { - m.Log_SELECT("env path cmd", file) + m.Logs(mdb.SELECT, "env path cmd", file) arg[0] = file // 环境变量 } } @@ -34,7 +34,7 @@ func _system_cmd(m *ice.Message, arg ...string) *exec.Cmd { if _system_find(m, arg[0]) == "" { m.Cmd(MIRRORS, CMD, arg[0]) if file := _system_find(m, arg[0]); file != "" { - m.Log_SELECT("mirrors cmd", file) + m.Logs(mdb.SELECT, "mirrors cmd", file) arg[0] = file // 软件镜像 } } @@ -42,7 +42,7 @@ func _system_cmd(m *ice.Message, arg ...string) *exec.Cmd { // 运行目录 if cmd.Dir = m.Option(CMD_DIR); len(cmd.Dir) > 0 { - if m.Log_EXPORT(CMD_DIR, cmd.Dir); !kit.FileExists(cmd.Dir) { + if m.Logs(mdb.EXPORT, CMD_DIR, cmd.Dir); !kit.FileExists(cmd.Dir) { file.MkdirAll(cmd.Dir, ice.MOD_DIR) } } @@ -51,7 +51,7 @@ func _system_cmd(m *ice.Message, arg ...string) *exec.Cmd { cmd.Env = append(cmd.Env, kit.Format("%s=%s", env[i], env[i+1])) } if len(cmd.Env) > 0 { - m.Log_EXPORT(CMD_ENV, cmd.Env) + m.Logs(mdb.EXPORT, CMD_ENV, kit.Format(cmd.Env)) } return cmd } @@ -61,7 +61,7 @@ func _system_out(m *ice.Message, out string) io.Writer { } else if m.Option(out) == "" { return nil } else if f, p, e := file.CreateFile(m.Option(out)); m.Assert(e) { - m.Log_EXPORT(out, p) + m.Logs(mdb.EXPORT, out, p) m.Optionv(out, f) return f } @@ -154,13 +154,6 @@ func init() { }) } -func PushStream(m *ice.Message) { - m.Option(CMD_OUTPUT, file.NewWriteCloser(func(buf []byte) (int, error) { - m.PushNoticeGrow(string(buf)) - return len(buf), nil - }, func() error { m.PushNoticeToast("done"); return nil })) -} - func IsSuccess(m *ice.Message) bool { return m.Append(CODE) == "0" || m.Append(CODE) == "" } diff --git a/base/ctx/command.go b/base/ctx/command.go index 99756fa9..b699fbad 100644 --- a/base/ctx/command.go +++ b/base/ctx/command.go @@ -15,11 +15,11 @@ func _command_list(m *ice.Message, name string) { if nfs.ExistsFile(m, path.Join(ice.SRC, name)) { switch kit.Ext(name) { case nfs.JS: - m.Push(DISPLAY, ice.FileURI(name)) - name = kit.Select(CAN_PLUGIN, ice.GetFileCmd(name)) + m.Push(DISPLAY, FileURI(name)) + name = kit.Select(CAN_PLUGIN, GetFileCmd(name)) case nfs.GO: - name = ice.GetFileCmd(name) + name = GetFileCmd(name) default: if msg := m.Cmd(mdb.RENDER, kit.Ext(name)); msg.Length() > 0 { @@ -110,7 +110,7 @@ func init() { func CmdAction(args ...ice.Any) ice.Actions { return ice.Actions{ice.CTX_INIT: mdb.AutoConfig(args...), COMMAND: {Name: "command", Help: "命令", Hand: func(m *ice.Message, arg ...string) { - if !m.PodCmd(COMMAND, arg) { + if !PodCmd(m, COMMAND, arg) { m.Cmdy(COMMAND, arg) } }}, @@ -119,9 +119,71 @@ func CmdAction(args ...ice.Any) ice.Actions { m.Cmd(CONFIG, "reset", arg[0]) return } - if m.Right(arg) && !m.PodCmd(arg) { + if aaa.Right(m, arg) && !PodCmd(m, arg) { m.Cmdy(arg) } }}, } } +func PodCmd(m *ice.Message, arg ...ice.Any) bool { + if pod := m.Option(ice.POD); pod != "" { + if m.Option(ice.POD, ""); m.Option(ice.MSG_UPLOAD) != "" { + msg := m.Cmd("cache", "upload") + m.Option(ice.MSG_UPLOAD, msg.Append(mdb.HASH), msg.Append(mdb.NAME), msg.Append(nfs.SIZE)) + } + m.Cmdy(append(kit.List("space", pod), arg...)) + return true + } + return false +} + +func FileURI(dir string) string { + if strings.Contains(dir, "go/pkg/mod") { + return path.Join("/require", strings.Split(dir, "go/pkg/mod")[1]) + } + if ice.Info.Make.Path != "" && strings.HasPrefix(dir, ice.Info.Make.Path+ice.PS) { + dir = strings.TrimPrefix(dir, ice.Info.Make.Path+ice.PS) + } + if strings.HasPrefix(dir, kit.Path("")+ice.PS) { + dir = strings.TrimPrefix(dir, kit.Path("")+ice.PS) + } + if strings.HasPrefix(dir, ice.USR) { + return path.Join("/require", dir) + } + if strings.HasPrefix(dir, ice.SRC) { + return path.Join("/require", dir) + } + if kit.FileExists(path.Join(ice.SRC, dir)) { + return path.Join("/require/src/", dir) + } + return dir +} +func FileCmd(dir string) string { + dir = strings.Split(dir, ice.DF)[0] + dir = strings.ReplaceAll(dir, ".js", ".go") + dir = strings.ReplaceAll(dir, ".sh", ".go") + return FileURI(dir) +} +func AddFileCmd(dir, key string) { + ice.Info.File[FileCmd(dir)] = key +} +func GetFileCmd(dir string) string { + if strings.HasPrefix(dir, "require/") { + dir = "/" + dir + } + for _, dir := range []string{dir, path.Join("/require/", ice.Info.Make.Module, dir), path.Join("/require/", ice.Info.Make.Module, ice.SRC, dir)} { + if cmd, ok := ice.Info.File[FileCmd(dir)]; ok { + return cmd + } + p := path.Dir(dir) + if cmd, ok := ice.Info.File[FileCmd(path.Join(p, path.Base(p)+".go"))]; ok { + return cmd + } + for k, v := range ice.Info.File { + if strings.HasPrefix(k, p) { + return v + } + } + } + return "" +} diff --git a/base/ctx/config.go b/base/ctx/config.go index 5056b160..25f7dcc4 100644 --- a/base/ctx/config.go +++ b/base/ctx/config.go @@ -28,7 +28,6 @@ func _config_save(m *ice.Message, name string, arg ...string) { // 保存配置 if s, e := json.MarshalIndent(data, "", " "); m.Assert(e) { if _, e := f.Write(s); m.Assert(e) { - // m.Log_EXPORT(CONFIG, name, nfs.FILE, p, nfs.SIZE, n) } } m.Echo(p) @@ -46,7 +45,6 @@ func _config_load(m *ice.Message, name string, arg ...string) { // 加载配置 for k, v := range data { msg.Search(k, func(p *ice.Context, s *ice.Context, key string) { - // m.Log_IMPORT(CONFIG, kit.Keys(s.Name, key), nfs.FILE, name) if s.Configs[key] == nil { s.Configs[key] = &ice.Config{} } @@ -124,7 +122,33 @@ func init() { return } _config_make(m, arg[0], arg[1:]...) - m.DisplayStoryJSON() + DisplayStoryJSON(m) }}, }) } +func init() { + ice.Info.Save = Save + ice.Info.Load = Load +} +func Save(m *ice.Message, arg ...string) *ice.Message { + if len(arg) == 0 { + for k := range m.Target().Configs { + arg = append(arg, k) + } + } + for i, k := range arg { + arg[i] = m.Prefix(k) + } + return m.Cmd(CONFIG, ice.SAVE, m.Prefix(nfs.JSON), arg) +} +func Load(m *ice.Message, arg ...string) *ice.Message { + if len(arg) == 0 { + for k := range m.Target().Configs { + arg = append(arg, k) + } + } + for i, k := range arg { + arg[i] = m.Prefix(k) + } + return m.Cmd(CONFIG, ice.LOAD, m.Prefix(nfs.JSON), arg) +} diff --git a/base/ctx/context.go b/base/ctx/context.go index c7494222..2c43aaa3 100644 --- a/base/ctx/context.go +++ b/base/ctx/context.go @@ -4,6 +4,7 @@ import ( "strings" ice "shylinux.com/x/icebergs" + "shylinux.com/x/icebergs/base/lex" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" kit "shylinux.com/x/toolkits" @@ -29,7 +30,7 @@ func init() { "spide": {Name: "spide", Help: "架构图", Hand: func(m *ice.Message, arg ...string) { if len(arg) == 0 || arg[1] == CONTEXT { // 模块列表 m.Cmdy(CONTEXT, kit.Select(ice.ICE, arg, 0), CONTEXT) - m.DisplayStorySpide("prefix", m.ActionKey(), nfs.ROOT, kit.Select(ice.ICE, arg, 0), "split", ice.PT) + DisplayStorySpide(m, lex.PREFIX, m.ActionKey(), nfs.ROOT, kit.Select(ice.ICE, arg, 0), lex.SPLIT, ice.PT) } else if index := kit.Keys(arg[1]); strings.HasSuffix(index, arg[2]) { // 命令列表 m.Cmdy(CONTEXT, index, COMMAND).Tables(func(value ice.Maps) { diff --git a/base/ctx/option.go b/base/ctx/option.go new file mode 100644 index 00000000..4a72bd7d --- /dev/null +++ b/base/ctx/option.go @@ -0,0 +1,60 @@ +package ctx + +import ( + "path" + "strings" + + ice "shylinux.com/x/icebergs" + kit "shylinux.com/x/toolkits" +) + +func ProcessCommand(m *ice.Message, cmd string, val []string, arg ...string) { + if len(arg) > 0 && arg[0] == ice.RUN { + m.Cmdy(cmd, arg[1:]) + return + } + + m.Cmdy(COMMAND, cmd) + m.ProcessField(cmd, ice.RUN) + m.Push(ice.ARG, kit.Format(val)) +} +func ProcessCommandOpt(m *ice.Message, arg []string, args ...string) { + if len(arg) > 0 && arg[0] == ice.RUN { + return + } + m.Push("opt", kit.Format(m.OptionSimple(args...))) +} +func DisplayTable(m *ice.Message, arg ...ice.Any) *ice.Message { // /plugin/story/file + return m.Display(kit.MergeURL("/plugin/table.js", arg...)) +} +func DisplayTableCard(m *ice.Message, arg ...ice.Any) *ice.Message { // /plugin/story/file + return m.Display(kit.MergeURL("/plugin/table.js", "style", "card")) +} +func DisplayStory(m *ice.Message, file string, arg ...ice.Any) *ice.Message { // /plugin/story/file + if !strings.HasPrefix(file, ice.HTTP) && !strings.HasPrefix(file, ice.PS) { + file = path.Join(ice.PLUGIN_STORY, file) + } + return DisplayBase(m, file, arg...) +} +func DisplayStoryJSON(m *ice.Message, arg ...ice.Any) *ice.Message { // /plugin/story/json.js + return DisplayStory(m, "json", arg...) +} +func DisplayStorySpide(m *ice.Message, arg ...ice.Any) *ice.Message { // /plugin/story/json.js + return DisplayStory(m, "spide", arg...).StatusTimeCount() +} +func DisplayLocal(m *ice.Message, file string, arg ...ice.Any) *ice.Message { // /plugin/local/file + if file == "" { + file = path.Join(kit.PathName(2), kit.Keys(kit.FileName(2), ice.JS)) + } + if !strings.HasPrefix(file, ice.HTTP) && !strings.HasPrefix(file, ice.PS) { + file = path.Join(ice.PLUGIN_LOCAL, file) + } + return DisplayBase(m, file, arg...) +} +func DisplayBase(m *ice.Message, file string, arg ...ice.Any) *ice.Message { + if !strings.Contains(file, ice.PT) { + file += ".js" + } + m.Option(ice.MSG_DISPLAY, kit.MergeURL(ice.DisplayBase(file)[ice.DISPLAY], arg...)) + return m +} diff --git a/base/gdb/event.go b/base/gdb/event.go index 2501dba6..db391786 100644 --- a/base/gdb/event.go +++ b/base/gdb/event.go @@ -22,3 +22,12 @@ func init() { }, mdb.ZoneAction(mdb.SHORT, EVENT, mdb.FIELD, "time,id,cmd"))}, }) } +func Watch(m *ice.Message, key string, arg ...string) *ice.Message { + if len(arg) == 0 { + arg = append(arg, m.Prefix(ice.AUTO)) + } + return m.Cmd(EVENT, LISTEN, EVENT, key, ice.CMD, kit.Join(arg, ice.SP)) +} +func Event(m *ice.Message, key string, arg ...string) *ice.Message { + return m.Cmd(EVENT, HAPPEN, EVENT, key, arg) +} diff --git a/base/gdb/gdb.go b/base/gdb/gdb.go index 0a4927b9..7a4fa4b5 100644 --- a/base/gdb/gdb.go +++ b/base/gdb/gdb.go @@ -28,7 +28,7 @@ func (f *Frame) Begin(m *ice.Message, arg ...string) ice.Server { delete(ice.Info.File, k) } - f.s = make(chan os.Signal, ice.MOD_CHAN) + f.s = make(chan os.Signal, 3) return f } func (f *Frame) Start(m *ice.Message, arg ...string) bool { @@ -59,8 +59,8 @@ func (f *Frame) Close(m *ice.Message, arg ...string) bool { const GDB = "gdb" var Index = &ice.Context{Name: GDB, Help: "事件模块", Commands: ice.Commands{ - ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { m.Load(TIMER, ROUTINE) }}, - ice.CTX_EXIT: {Hand: func(m *ice.Message, arg ...string) { m.Save(TIMER, ROUTINE) }}, + ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { ice.Info.Load(m, TIMER, ROUTINE) }}, + ice.CTX_EXIT: {Hand: func(m *ice.Message, arg ...string) { ice.Info.Save(m, TIMER, ROUTINE) }}, }} func init() { ice.Index.Register(Index, &Frame{}, SIGNAL, TIMER, EVENT, ROUTINE) } diff --git a/base/gdb/routine.go b/base/gdb/routine.go index 45deafbc..29c3dea2 100644 --- a/base/gdb/routine.go +++ b/base/gdb/routine.go @@ -1,8 +1,6 @@ package gdb import ( - "path" - ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/mdb" kit "shylinux.com/x/toolkits" @@ -16,7 +14,7 @@ func init() { ROUTINE: {Name: "routine hash auto prunes", Help: "协程池", Actions: ice.MergeAction(ice.Actions{ mdb.CREATE: {Name: "create name", Help: "创建", Hand: func(m *ice.Message, arg ...string) { m.Go(func() { - cb := m.OptionCB(ROUTINE) + cb := m.OptionCB("") h := mdb.HashCreate(m, m.OptionSimple(mdb.NAME), mdb.STATUS, START, ice.CMD, logs.FileLine(cb, 100)).Result() defer func() { if e := recover(); e == nil { @@ -37,10 +35,6 @@ func init() { } }) }}, - "inner": {Name: "inner", Help: "源码", Hand: func(m *ice.Message, arg ...string) { - ls := kit.Split(m.Option(ice.CMD), ":") - m.ProcessCommand("inner", []string{path.Dir(ls[0]), path.Base(ls[0]), ls[1]}, arg...) - }}, - }, mdb.HashActionStatus(mdb.FIELD, "time,hash,name,status,cmd", mdb.ACTION, "inner"))}, + }, mdb.HashStatusAction(mdb.FIELD, "time,hash,name,status,cmd"))}, }) } diff --git a/base/gdb/signal.go b/base/gdb/signal.go index 40fd4493..3f4a969f 100644 --- a/base/gdb/signal.go +++ b/base/gdb/signal.go @@ -8,7 +8,6 @@ import ( ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/mdb" - "shylinux.com/x/icebergs/base/nfs" kit "shylinux.com/x/toolkits" "shylinux.com/x/toolkits/logs" ) @@ -26,7 +25,7 @@ func _signal_action(m *ice.Message, arg ...string) { } func _signal_process(m *ice.Message, p string, s os.Signal) { if p == "" { - p = m.Cmdx(nfs.CAT, ice.Info.PidPath) + p = logs.ReadFile(ice.Info.PidPath) } if p == "" { p = kit.Format(os.Getpid()) @@ -40,13 +39,13 @@ const ( PID = "pid" ) const ( - LISTEN = ice.LISTEN - HAPPEN = ice.HAPPEN + LISTEN = "listen" + HAPPEN = "happen" - START = ice.START - RESTART = ice.RESTART - STOP = ice.STOP - ERROR = ice.ERROR + START = "start" + RESTART = "restart" + STOP = "stop" + ERROR = "error" KILL = "kill" ) const SIGNAL = "signal" @@ -60,7 +59,7 @@ func init() { if f, p, e := logs.CreateFile(ice.Info.PidPath); !m.Warn(e) { defer f.Close() fmt.Fprint(f, os.Getpid()) - m.Log_CREATE(nfs.FILE, p) + m.Logs(mdb.CREATE, PID, p) } }}, LISTEN: {Name: "listen signal name cmd", Help: "监听", Hand: func(m *ice.Message, arg ...string) { diff --git a/base/gdb/timer.go b/base/gdb/timer.go index e2aa64ff..ff785fc1 100644 --- a/base/gdb/timer.go +++ b/base/gdb/timer.go @@ -16,7 +16,7 @@ func _timer_action(m *ice.Message, now time.Time, arg ...string) { if kit.Time(value[mdb.TIME]) > kit.Int64(now) { return } - m.Cmd(ROUTINE, mdb.CREATE, mdb.NAME, "some", kit.Keycb(ROUTINE), value[ice.CMD]) + m.Cmd(ROUTINE, mdb.CREATE, mdb.NAME, value[mdb.NAME], kit.Keycb(ROUTINE), value[ice.CMD]) mdb.HashModify(m, mdb.HASH, value[mdb.HASH], mdb.COUNT, kit.Int(value[mdb.COUNT])-1, mdb.TIME, m.Time(value[INTERVAL])) }) } diff --git a/base/lex/matrix.go b/base/lex/matrix.go index 3b81cb4b..7722fdd7 100644 --- a/base/lex/matrix.go +++ b/base/lex/matrix.go @@ -7,7 +7,6 @@ import ( "strings" ice "shylinux.com/x/icebergs" - "shylinux.com/x/icebergs/base/cli" "shylinux.com/x/icebergs/base/mdb" kit "shylinux.com/x/toolkits" ) @@ -346,10 +345,10 @@ func (mat *Matrix) show(m *ice.Message) { value = append(value, "*") } if node.next > 0 { - value = append(value, cli.ColorGreen(m, node.next)) + // value = append(value, cli.ColorGreen(m, node.next)) } if node.hash > 0 { - value = append(value, cli.ColorRed(m, kit.Select(kit.Format("%d", node.hash), mat.word[node.hash]))) + // value = append(value, cli.ColorRed(m, kit.Select(kit.Format("%d", node.hash), mat.word[node.hash]))) } } m.Push(key, strings.Join(value, ",")) @@ -359,11 +358,11 @@ func (mat *Matrix) show(m *ice.Message) { m.Status(NLANG, mat.nlang, NCELL, mat.ncell, NPAGE, len(mat.page), NHASH, len(mat.hash)) } func _lex_load(m *ice.Message) { - m.Richs(m.PrefixKey(), "", mdb.FOREACH, func(key string, value ice.Map) { + mdb.Richs(m, m.PrefixKey(), "", mdb.FOREACH, func(key string, value ice.Map) { value = kit.GetMeta(value) mat := NewMatrix(m, kit.Int(kit.Select("32", value[NLANG])), kit.Int(kit.Select("256", value[NCELL]))) - m.Grows(m.PrefixKey(), kit.Keys(mdb.HASH, key), "", "", func(index int, value ice.Map) { + mdb.Grows(m, m.PrefixKey(), kit.Keys(mdb.HASH, key), "", "", func(index int, value ice.Map) { mat.Train(m, kit.Format(value[NPAGE]), kit.Format(value[NHASH]), kit.Format(value[mdb.TEXT])) }) value[MATRIX] = mat @@ -392,7 +391,7 @@ func init() { }}, mdb.CREATE: {Name: "create nlang=32 ncell=128", Help: "创建", Hand: func(m *ice.Message, arg ...string) { mat := NewMatrix(m, kit.Int(kit.Select("32", m.Option(NLANG))), kit.Int(kit.Select("128", m.Option(NCELL)))) - h := m.Rich(m.PrefixKey(), "", kit.Data(mdb.TIME, m.Time(), MATRIX, mat, NLANG, mat.nlang, NCELL, mat.ncell)) + h := mdb.Rich(m, m.PrefixKey(), "", kit.Data(mdb.TIME, m.Time(), MATRIX, mat, NLANG, mat.nlang, NCELL, mat.ncell)) switch cb := m.OptionCB(MATRIX).(type) { case func(string, *Matrix): cb(h, mat) @@ -402,12 +401,12 @@ func init() { m.Echo(h) }}, mdb.INSERT: {Name: "insert hash npage=num nhash=num text=123", Help: "添加", Hand: func(m *ice.Message, arg ...string) { - m.Richs(m.PrefixKey(), "", m.Option(mdb.HASH), func(key string, value ice.Map) { + mdb.Richs(m, m.PrefixKey(), "", m.Option(mdb.HASH), func(key string, value ice.Map) { value = kit.GetMeta(value) mat, _ := value[MATRIX].(*Matrix) m.Echo("%d", mat.Train(m, m.Option(NPAGE), m.Option(NHASH), m.Option(mdb.TEXT))) - m.Grow(m.PrefixKey(), kit.Keys(mdb.HASH, key), kit.Dict( + mdb.Grow(m, m.PrefixKey(), kit.Keys(mdb.HASH, key), kit.Dict( mdb.TIME, m.Time(), NPAGE, m.Option(NPAGE), NHASH, m.Option(NHASH), mdb.TEXT, m.Option(mdb.TEXT), )) @@ -419,7 +418,7 @@ func init() { m.Cmdy(mdb.DELETE, m.PrefixKey(), "", mdb.HASH, mdb.HASH, m.Option(mdb.HASH)) }}, PARSE: {Name: "parse hash npage text=123", Help: "解析", Hand: func(m *ice.Message, arg ...string) { - m.Richs(m.PrefixKey(), "", m.Option(mdb.HASH), func(key string, value ice.Map) { + mdb.Richs(m, m.PrefixKey(), "", m.Option(mdb.HASH), func(key string, value ice.Map) { value = kit.GetMeta(value) mat, _ := value[MATRIX].(*Matrix) @@ -432,7 +431,7 @@ func init() { m.ProcessInner() }}, "show": {Name: "show", Help: "矩阵", Hand: func(m *ice.Message, arg ...string) { - m.Richs(m.PrefixKey(), "", kit.Select(m.Option(mdb.HASH), arg, 0), func(key string, value ice.Map) { + mdb.Richs(m, m.PrefixKey(), "", kit.Select(m.Option(mdb.HASH), arg, 0), func(key string, value ice.Map) { value = kit.GetMeta(value) value[MATRIX].(*Matrix).show(m) }) @@ -462,9 +461,9 @@ func init() { m.Push("value", 2) m.ProcessDisplay("/plugin/story/pie.js") }}, - "field": {Hand: func(m *ice.Message, arg ...string) { - m.ProcessCommand("cli.system", []string{"pwd"}, arg...) - }}, + // "field": {Hand: func(m *ice.Message, arg ...string) { + // m.ProcessCommand("cli.system", []string{"pwd"}, arg...) + // }}, "inner": {Hand: func(m *ice.Message, arg ...string) { m.Push("value", 1) m.Push("value", 2) @@ -521,7 +520,7 @@ func init() { return } - m.Richs(m.PrefixKey(), "", arg[0], func(key string, value ice.Map) { + mdb.Richs(m, m.PrefixKey(), "", arg[0], func(key string, value ice.Map) { value = kit.GetMeta(value) mat, _ := value[MATRIX].(*Matrix) diff --git a/base/lex/split.go b/base/lex/split.go index 289d9c70..0b35be19 100644 --- a/base/lex/split.go +++ b/base/lex/split.go @@ -107,7 +107,7 @@ func init() { m.Cmdy(nfs.DIR, arg) return } - m.Echo(kit.Format(_split_list(m, arg[0], kit.Split(kit.Join(arg[1:]))...))).DisplayStoryJSON() + m.Echo(kit.Format(_split_list(m, arg[0], kit.Split(kit.Join(arg[1:]))...))) }}, }) } diff --git a/base/log/log.go b/base/log/log.go index 68fa68f6..72556123 100644 --- a/base/log/log.go +++ b/base/log/log.go @@ -2,9 +2,7 @@ package log import ( "bufio" - "os" "path" - "strings" ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/mdb" @@ -26,13 +24,6 @@ func (f *Frame) Spawn(m *ice.Message, c *ice.Context, arg ...string) ice.Server return &Frame{} } func (f *Frame) Begin(m *ice.Message, arg ...string) ice.Server { - switch strings.Split(os.Getenv("TERM"), "-")[0] { - case "xterm", "screen": - ice.Info.Colors = true - default: - ice.Info.Colors = false - } - f.p = make(chan *Log, ice.MOD_BUFS) ice.Info.Log = func(msg *ice.Message, p, l, s string) { f.p <- &Log{m: msg, p: p, l: l, s: s} @@ -106,10 +97,10 @@ var Index = &ice.Context{Name: "log", Help: "日志模块", Configs: ice.Configs FILE: {Name: FILE, Help: "日志文件", Value: kit.Dict( BENCH, kit.Dict(nfs.PATH, path.Join(ice.VAR_LOG, "bench.log"), mdb.LIST, []string{}), WATCH, kit.Dict(nfs.PATH, path.Join(ice.VAR_LOG, "watch.log"), mdb.LIST, []string{ - ice.LOG_CREATE, ice.LOG_REMOVE, - ice.LOG_INSERT, ice.LOG_DELETE, - ice.LOG_MODIFY, ice.LOG_SELECT, - ice.LOG_EXPORT, ice.LOG_IMPORT, + mdb.CREATE, mdb.REMOVE, + mdb.INSERT, mdb.DELETE, + mdb.MODIFY, mdb.SELECT, + mdb.EXPORT, mdb.IMPORT, }), ERROR, kit.Dict(nfs.PATH, path.Join(ice.VAR_LOG, "error.log"), mdb.LIST, []string{ ice.LOG_WARN, ice.LOG_ERROR, @@ -120,21 +111,18 @@ var Index = &ice.Context{Name: "log", Help: "日志模块", Configs: ice.Configs )}, VIEW: {Name: VIEW, Help: "日志格式", Value: kit.Dict( GREEN, kit.Dict(PREFIX, "\033[32m", SUFFIX, "\033[0m", mdb.LIST, []string{ - ice.LOG_START, ice.LOG_SERVE, ice.LOG_CMDS, + ice.CTX_START, ice.LOG_CMDS, }), YELLOW, kit.Dict(PREFIX, "\033[33m", SUFFIX, "\033[0m", mdb.LIST, []string{ ice.LOG_AUTH, ice.LOG_COST, }), RED, kit.Dict(PREFIX, "\033[31m", SUFFIX, "\033[0m", mdb.LIST, []string{ - ice.LOG_CLOSE, ice.LOG_WARN, + ice.CTX_CLOSE, ice.LOG_WARN, }), )}, SHOW: {Name: SHOW, Help: "日志分流", Value: kit.Dict()}, }, Commands: ice.Commands{ ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { - if !strings.Contains(ice.Getenv("ctx_daemon"), "log") { - return // 没有日志 - } m.Confm(VIEW, nil, func(key string, value ice.Map) { kit.Fetch(value[mdb.LIST], func(index int, k string) { m.Conf(SHOW, kit.Keys(k, VIEW), key) @@ -148,7 +136,7 @@ var Index = &ice.Context{Name: "log", Help: "日志模块", Configs: ice.Configs if f, p, e := logs.CreateFile(kit.Format(value[nfs.PATH])); m.Assert(e) { m.Cap(ice.CTX_STREAM, path.Base(p)) value[FILE] = bufio.NewWriter(f) - m.Log_CREATE(nfs.FILE, p) + m.Logs(mdb.CREATE, nfs.FILE, p) } }) }}, diff --git a/base/mdb/hash.go b/base/mdb/hash.go index ce3a1c4e..f904be29 100644 --- a/base/mdb/hash.go +++ b/base/mdb/hash.go @@ -2,6 +2,7 @@ package mdb import ( "encoding/json" + "io" "path" ice "shylinux.com/x/icebergs" @@ -12,22 +13,11 @@ import ( func _hash_fields(m *ice.Message) []string { return kit.Split(kit.Select(HASH_FIELD, m.OptionFields())) } -func _hash_select_fields(m *ice.Message, prefix, chain string, key string, field string) (value string) { - defer m.RLock(prefix, chain)() - m.Richs(prefix, chain, key, func(h string, v Map) { - if field == HASH { - value = h - } else { - value = kit.Format(v[field]) - } - }) - return -} func _hash_inputs(m *ice.Message, prefix, chain string, field, value string) { - defer m.RLock(prefix, chain)() + defer RLock(m, prefix, chain)() list := map[string]int{} - m.Richs(prefix, chain, FOREACH, func(val Map) { + Richs(m, prefix, chain, FOREACH, func(val Map) { val = kit.GetMeta(val) list[kit.Format(val[field])] += kit.Int(kit.Select("1", val[COUNT])) }) @@ -38,7 +28,7 @@ func _hash_inputs(m *ice.Message, prefix, chain string, field, value string) { m.SortIntR(COUNT) } func _hash_insert(m *ice.Message, prefix, chain string, arg ...string) string { - defer m.Lock(prefix, chain)() + defer Lock(m, prefix, chain)() if value := m.Confm(prefix, kit.Keys(HASH, arg[1])); value != nil && arg[1] != "" { value = kit.GetMeta(value) @@ -48,58 +38,63 @@ func _hash_insert(m *ice.Message, prefix, chain string, arg ...string) string { return arg[1] } - m.Log_INSERT(KEY, path.Join(prefix, chain), arg[0], arg[1]) + m.Logs(INSERT, KEY, path.Join(prefix, chain), arg[0], arg[1]) if expire := m.Conf(prefix, kit.Keys(chain, kit.Keym(EXPIRE))); expire != "" { arg = kit.Simple(TIME, m.Time(expire), arg) } - if m.Option(ice.MSG_DOMAIN) != "" { - m.Conf(prefix, kit.Keys(chain, kit.Keym(SHORT)), m.Conf(prefix, kit.Keym(SHORT))) - } if m.Optionv(TARGET) != nil { - m.Echo(m.Rich(prefix, chain, kit.Data(arg, TARGET, m.Optionv(TARGET)))) + m.Echo(Rich(m, prefix, chain, kit.Data(arg, TARGET, m.Optionv(TARGET)))) } else { - m.Echo(m.Rich(prefix, chain, kit.Data(arg))) + m.Echo(Rich(m, prefix, chain, kit.Data(arg))) } return m.Result() } func _hash_delete(m *ice.Message, prefix, chain, field, value string) { - defer m.Lock(prefix, chain)() + defer Lock(m, prefix, chain)() - if field != HASH { - field, value = HASH, kit.Select(kit.Hashs(value), m.Option(HASH)) - } - m.Richs(prefix, chain, value, func(key string, val Map) { - m.Log_DELETE(KEY, path.Join(prefix, chain), field, value, VALUE, kit.Format(val)) + Richs(m, prefix, chain, value, func(key string, val Map) { + m.Logs(DELETE, KEY, path.Join(prefix, chain), field, value, VALUE, kit.Format(val)) m.Conf(prefix, kit.Keys(chain, HASH, key), "") }) } func _hash_modify(m *ice.Message, prefix, chain string, field, value string, arg ...string) { - defer m.Lock(prefix, chain)() + defer Lock(m, prefix, chain)() - m.Richs(prefix, chain, value, func(key string, val Map) { - m.Log_MODIFY(KEY, path.Join(prefix, chain), field, value, arg) + Richs(m, prefix, chain, value, func(key string, val Map) { + m.Logs(MODIFY, KEY, path.Join(prefix, chain), field, value, arg) _mdb_modify(m, val, field, arg...) }) } func _hash_select(m *ice.Message, prefix, chain, field, value string) { - defer m.RLock(prefix, chain)() + defer RLock(m, prefix, chain)() if field == HASH && value == RANDOM { value = RANDOMS } fields := _hash_fields(m) - m.Richs(prefix, chain, value, func(key string, value Map) { - _mdb_select(m, key, value, fields, nil) + Richs(m, prefix, chain, value, func(key string, value Map) { + _mdb_select(m, m.OptionCB(""), key, value, fields, nil) }) if !m.FieldsIsDetail() { m.SortTimeR(TIME) } } +func _hash_select_field(m *ice.Message, prefix, chain string, key string, field string) (value string) { + defer RLock(m, prefix, chain)() + Richs(m, prefix, chain, key, func(h string, v Map) { + if field == HASH { + value = h + } else { + value = kit.Format(v[field]) + } + }) + return +} func _hash_prunes(m *ice.Message, prefix, chain string, arg ...string) { - defer m.RLock(prefix, chain)() + defer RLock(m, prefix, chain)() fields := _hash_fields(m) - m.Richs(prefix, chain, FOREACH, func(key string, val Map) { + Richs(m, prefix, chain, FOREACH, func(key string, val Map) { switch val = kit.GetMeta(val); cb := m.OptionCB(PRUNES).(type) { case func(string, Map) bool: if !cb(key, val) { @@ -116,7 +111,7 @@ func _hash_prunes(m *ice.Message, prefix, chain string, arg ...string) { }) } func _hash_export(m *ice.Message, prefix, chain, file string) { - defer m.Lock(prefix, chain)() + defer Lock(m, prefix, chain)() f, p, e := miss.CreateFile(kit.Keys(file, JSON)) m.Assert(e) @@ -126,12 +121,12 @@ func _hash_export(m *ice.Message, prefix, chain, file string) { en.SetIndent("", " ") m.Assert(en.Encode(m.Confv(prefix, kit.Keys(chain, HASH)))) - m.Log_EXPORT(KEY, path.Join(prefix, chain), FILE, p) + m.Logs(EXPORT, KEY, path.Join(prefix, chain), FILE, p) m.Conf(prefix, kit.Keys(chain, HASH), "") m.Echo(p) } func _hash_import(m *ice.Message, prefix, chain, file string) { - defer m.Lock(prefix, chain)() + defer Lock(m, prefix, chain)() f, e := miss.OpenFile(kit.Keys(file, JSON)) m.Assert(e) @@ -148,12 +143,12 @@ func _hash_import(m *ice.Message, prefix, chain, file string) { } } else { for _, data := range list { - m.Rich(prefix, chain, data) + Rich(m, prefix, chain, data) count++ } } - m.Log_IMPORT(KEY, path.Join(prefix, chain), COUNT, count) + m.Logs(IMPORT, KEY, path.Join(prefix, chain), COUNT, count) m.Echo("%d", count) } @@ -168,24 +163,33 @@ func HashAction(args ...Any) ice.Actions { CREATE: {Name: "create", Help: "创建", Hand: func(m *ice.Message, arg ...string) { HashCreate(m, arg) }}, REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) { HashRemove(m, arg) }}, MODIFY: {Name: "modify", Help: "编辑", Hand: func(m *ice.Message, arg ...string) { HashModify(m, arg) }}, - SELECT: {Name: "select hash auto", Help: "列表", Hand: func(m *ice.Message, arg ...string) { HashSelect(m, arg...) }}, + SELECT: {Name: "select", Help: "列表", Hand: func(m *ice.Message, arg ...string) { HashSelect(m, arg...) }}, PRUNES: {Name: "prunes before@date", Help: "清理", Hand: func(m *ice.Message, arg ...string) { HashPrunes(m, nil) }}, EXPORT: {Name: "export", Help: "导出", Hand: func(m *ice.Message, arg ...string) { HashExport(m, arg) }}, IMPORT: {Name: "import", Help: "导入", Hand: func(m *ice.Message, arg ...string) { HashImport(m, arg) }}, } } -func HashActionStatus(args ...Any) ice.Actions { +func HashCloseAction(args ...Any) ice.Actions { + return ice.MergeAction(HashAction(args...), ice.Actions{ + ice.CTX_EXIT: {Hand: func(m *ice.Message, arg ...string) { HashSelectClose(m) }}, + }) +} +func HashStatusAction(args ...Any) ice.Actions { list := HashAction(args...) list[PRUNES] = &ice.Action{Name: "prunes", Help: "清理", Hand: func(m *ice.Message, arg ...string) { m.OptionFields(m.Config(FIELD)) - m.Cmdy(PRUNES, m.PrefixKey(), "", HASH, STATUS, ice.ERROR) - m.Cmdy(PRUNES, m.PrefixKey(), "", HASH, STATUS, ice.CLOSE) - m.Cmdy(PRUNES, m.PrefixKey(), "", HASH, STATUS, ice.STOP) - m.Cmdy(PRUNES, m.PrefixKey(), "", HASH, STATUS, ice.END) - m.Tables(func(value ice.Maps) { HashRemove(m, HASH, value[HASH]) }) + m.Cmdy(PRUNES, m.PrefixKey(), "", HASH, STATUS, "error") + m.Cmdy(PRUNES, m.PrefixKey(), "", HASH, STATUS, "close") + m.Cmdy(PRUNES, m.PrefixKey(), "", HASH, STATUS, "stop") + m.Cmdy(PRUNES, m.PrefixKey(), "", HASH, STATUS, "end") }} return list } +func HashStatusCloseAction(args ...Any) ice.Actions { + return ice.MergeAction(HashStatusAction(args...), ice.Actions{ + ice.CTX_EXIT: {Hand: func(m *ice.Message, arg ...string) { HashSelectClose(m) }}, + }) +} func HashShort(m *ice.Message) string { return kit.Select(HASH, m.Config(SHORT), m.Config(SHORT) != UNIQ) @@ -211,16 +215,19 @@ func HashSelect(m *ice.Message, arg ...string) *ice.Message { m.Cmdy(SELECT, m.PrefixKey(), "", HASH, HashShort(m), arg) if m.PushAction(m.Config(ACTION), REMOVE); !m.FieldsIsDetail() { return m.StatusTimeCount() - } else { - return m.StatusTime() } + return m.StatusTime() } func HashPrunes(m *ice.Message, cb func(Maps) bool) *ice.Message { expire := kit.Time(kit.Select(m.Time("-72h"), m.Option(EXPIRE))) - m.Cmd(m.CommandKey()).Tables(func(value Maps) { - if cb != nil && !cb(value) || kit.Time(value[TIME]) < expire { - HashRemove(m, HashShort(m), value[HashShort(m)]) + m.Cmd("", func(value Maps) { + if kit.Time(value[TIME]) > expire { + return } + if cb != nil && !cb(value) { + return + } + HashRemove(m, HashShort(m), value[HashShort(m)]) }) return m } @@ -232,7 +239,6 @@ func HashImport(m *ice.Message, arg ...Any) *ice.Message { } func HashTarget(m *ice.Message, h string, add func() Any) (p Any) { - m.Assert(h != "") HashSelectUpdate(m, h, func(value ice.Map) { p = value[TARGET] if pp, ok := p.(Map); ok && len(pp) == 0 { @@ -249,7 +255,7 @@ func HashPrunesValue(m *ice.Message, field, value string) { m.OptionFields(m.Config(FIELD)) m.Cmdy(PRUNES, m.PrefixKey(), "", HASH, field, value) } -func HashSelectFields(m *ice.Message, key string, field string) (value string) { +func HashSelectField(m *ice.Message, key string, field string) (value string) { HashSelectDetail(m, key, func(h string, val ice.Map) { if field == HASH { value = h @@ -260,45 +266,33 @@ func HashSelectFields(m *ice.Message, key string, field string) (value string) { return } func HashSelectDetail(m *ice.Message, key string, cb Any) bool { - defer m.RLock(m.PrefixKey(), "")() + defer RLock(m, m.PrefixKey(), "")() has := false - m.Richs(m.PrefixKey(), nil, key, func(key string, value Map) { - hashSelect(m, key, value, cb) + Richs(m, m.PrefixKey(), nil, key, func(key string, value Map) { + _mdb_select(m, cb, key, value, nil, nil) has = true }) return has } func HashSelectUpdate(m *ice.Message, key string, cb Any) *ice.Message { - defer m.Lock(m.PrefixKey(), "")() - m.Richs(m.PrefixKey(), nil, key, func(key string, value Map) { - hashSelect(m, key, value, cb) + defer Lock(m, m.PrefixKey(), "")() + Richs(m, m.PrefixKey(), nil, key, func(key string, value Map) { + _mdb_select(m, cb, key, value, nil, nil) }) return m } -func HashSelectSearch(m *ice.Message, args []string, keys ...string) *ice.Message { - if len(keys) == 0 { - ls := kit.Split(m.Config(FIELD)) - for _, k := range ls { - switch k { - case TIME, HASH: - default: - keys = append(keys, k) - } - } - } - if args[0] == m.CommandKey() { - HashSelectValue(m, func(value ice.Map) { - if args[1] == "" || args[1] == value[keys[1]] { - m.PushSearch(kit.SimpleKV("", value[keys[0]], value[keys[1]], value[keys[2]]), value) - } - }) - } +func HashSelectValue(m *ice.Message, cb Any) *ice.Message { + defer RLock(m, m.PrefixKey(), "")() + Richs(m, m.PrefixKey(), nil, FOREACH, func(key string, value Map) { + _mdb_select(m, cb, key, value, nil, nil) + }) return m } -func HashSelectValue(m *ice.Message, cb Any) *ice.Message { - defer m.RLock(m.PrefixKey(), "")() - m.Richs(m.PrefixKey(), nil, FOREACH, func(key string, value Map) { - hashSelect(m, key, value, cb) +func HashSelectClose(m *ice.Message) *ice.Message { + HashSelectValue(m, func(target ice.Any) { + if c, ok := target.(io.Closer); ok { + c.Close() + } }) return m } @@ -306,17 +300,20 @@ func HashSelects(m *ice.Message, arg ...string) *ice.Message { m.OptionFields(m.Config(FIELD)) return HashSelect(m, arg...) } -func hashSelect(m *ice.Message, key string, value Map, cb Any) *ice.Message { - switch value = kit.GetMeta(value); cb := cb.(type) { - case func(string, Map): - cb(key, value) - case func(Map): - cb(value) - case func(Any): - cb(value[TARGET]) - case nil: - default: - m.ErrorNotImplement(cb) + +func Richs(m *ice.Message, prefix string, chain Any, raw Any, cb Any) (res Map) { + cache := m.Confm(prefix, chain) + if cache == nil { + return nil } - return m + return miss.Richs(path.Join(prefix, kit.Keys(chain)), cache, raw, cb) + +} +func Rich(m *ice.Message, prefix string, chain Any, data Any) string { + cache := m.Confm(prefix, chain) + if cache == nil { + cache = kit.Data() + m.Confv(prefix, chain, cache) + } + return miss.Rich(path.Join(prefix, kit.Keys(chain)), cache, data) } diff --git a/base/mdb/list.go b/base/mdb/list.go index 6491e168..c52a91f5 100644 --- a/base/mdb/list.go +++ b/base/mdb/list.go @@ -3,6 +3,7 @@ package mdb import ( "encoding/csv" "path" + "strings" ice "shylinux.com/x/icebergs" kit "shylinux.com/x/toolkits" @@ -13,10 +14,10 @@ func _list_fields(m *ice.Message) []string { return kit.Split(kit.Select(LIST_FIELD, m.OptionFields())) } func _list_inputs(m *ice.Message, prefix, chain string, field, value string) { - defer m.RLock(prefix, chain)() + defer RLock(m, prefix, chain)() list := map[string]int{} - m.Grows(prefix, chain, "", "", func(val ice.Map) { + Grows(m, prefix, chain, "", "", func(val ice.Map) { val = kit.GetMeta(val) list[kit.Format(val[field])] += kit.Int(kit.Select("1", val[COUNT])) }) @@ -27,32 +28,29 @@ func _list_inputs(m *ice.Message, prefix, chain string, field, value string) { m.SortIntR(COUNT) } func _list_insert(m *ice.Message, prefix, chain string, arg ...string) { - defer m.Lock(prefix, chain)() + defer Lock(m, prefix, chain)() - m.Log_INSERT(KEY, path.Join(prefix, chain), arg[0], arg[1]) - m.Echo("%d", m.Grow(prefix, chain, kit.Dict(arg))) + m.Logs(INSERT, KEY, path.Join(prefix, chain), arg[0], arg[1]) + m.Echo("%d", Grow(m, prefix, chain, kit.Dict(arg))) } func _list_modify(m *ice.Message, prefix, chain string, field, value string, arg ...string) { - defer m.Lock(prefix, chain)() + defer Lock(m, prefix, chain)() - m.Grows(prefix, chain, field, value, func(index int, val ice.Map) { - m.Log_MODIFY(KEY, path.Join(prefix, chain), field, value, arg) + Grows(m, prefix, chain, field, value, func(index int, val ice.Map) { + m.Logs(MODIFY, KEY, path.Join(prefix, chain), field, value, arg) _mdb_modify(m, val, field, arg...) }) } func _list_select(m *ice.Message, prefix, chain, field, value string) { - defer m.RLock(prefix, chain)() + defer RLock(m, prefix, chain)() - if value == "" { - field = "" - } fields := _list_fields(m) - m.Grows(prefix, chain, kit.Select(m.Option(ice.CACHE_FIELD), field), kit.Select(m.Option(ice.CACHE_VALUE), value), func(value ice.Map) { - _mdb_select(m, "", value, fields, nil) + Grows(m, prefix, chain, kit.Select(m.Option(CACHE_FIELD), field), kit.Select(m.Option(CACHE_VALUE), value), func(value ice.Map) { + _mdb_select(m, m.OptionCB(""), "", value, fields, nil) }) } func _list_export(m *ice.Message, prefix, chain, file string) { - defer m.RLock(prefix, chain)() + defer RLock(m, prefix, chain)() f, p, e := miss.CreateFile(kit.Keys(file, CSV)) m.Assert(e) @@ -63,9 +61,9 @@ func _list_export(m *ice.Message, prefix, chain, file string) { count := 0 head := kit.Split(m.Config(FIELD)) - m.Grows(prefix, chain, "", "", func(index int, val ice.Map) { + Grows(m, prefix, chain, "", "", func(index int, val ice.Map) { if val = kit.GetMeta(val); index == 0 { - if len(head) == 0 || head[0] == ice.CACHE_DETAIL { // 默认表头 + if len(head) == 0 || head[0] == ice.FIELDS_DETAIL { // 默认表头 for k := range val { head = append(head, k) } @@ -82,13 +80,13 @@ func _list_export(m *ice.Message, prefix, chain, file string) { count++ }) - m.Log_EXPORT(KEY, path.Join(prefix, chain), FILE, p, COUNT, count) + m.Logs(EXPORT, KEY, path.Join(prefix, chain), FILE, p, COUNT, count) m.Conf(prefix, kit.Keys(chain, kit.Keym(COUNT)), 0) m.Conf(prefix, kit.Keys(chain, LIST), "") m.Echo(p) } func _list_import(m *ice.Message, prefix, chain, file string) { - defer m.RLock(prefix, chain)() + defer RLock(m, prefix, chain)() f, e := miss.OpenFile(kit.Keys(file, CSV)) m.Assert(e) @@ -113,11 +111,11 @@ func _list_import(m *ice.Message, prefix, chain, file string) { } } - m.Grow(prefix, chain, data) + Grow(m, prefix, chain, data) count++ } - m.Log_IMPORT(KEY, kit.Keys(prefix, chain), COUNT, count) + m.Logs(IMPORT, KEY, kit.Keys(prefix, chain), COUNT, count) m.Echo("%d", count) } @@ -165,7 +163,7 @@ func ListArgs(m *ice.Message, arg ...ice.Any) []string { return _mdb_args(m, ListField(m), arg...) } func ListSelect(m *ice.Message, arg ...string) *ice.Message { - m.OptionPage(kit.Slice(arg, 1)...) + OptionPage(m, kit.Slice(arg, 1)...) m.Fields(len(kit.Slice(arg, 0, 1)), ListField(m)) if m.Cmdy(SELECT, m.PrefixKey(), "", LIST, ID, arg); !m.FieldsIsDetail() { m.StatusTimeCountTotal(m.Config(COUNT)) @@ -178,16 +176,14 @@ func PrevPageLimit(m *ice.Message, total string, arg ...string) { if kit.Int(kit.Select("0", arg, 1)) > 0 { PrevPage(m, total, arg...) } else { - m.Toast("已经是最前一页啦!") - m.ProcessHold() + m.ProcessHold("已经最前一页啦!") } } func PrevPage(m *ice.Message, total string, arg ...string) { limit, offend := kit.Select("10", arg, 0), kit.Select("0", arg, 1) offends := kit.Int(offend) - kit.Int(limit) if total != "0" && (offends <= -kit.Int(total) || offends >= kit.Int(total)) { - m.Toast("已经是最前一页啦!") - m.ProcessHold() + m.ProcessHold("已经是最前一页啦!") return } if offends == 0 { @@ -201,8 +197,7 @@ func NextPage(m *ice.Message, total string, arg ...string) { limit, offend := kit.Select("10", arg, 0), kit.Select("0", arg, 1) offends := kit.Int(offend) + kit.Int(limit) if total != "0" && (offends <= -kit.Int(total) || offends >= kit.Int(total)) { - m.Toast("已经是最后一页啦!") - m.ProcessHold() + m.ProcessHold("已经是最后一页啦!") return } if offends == 0 { @@ -215,7 +210,61 @@ func NextPageLimit(m *ice.Message, total string, arg ...string) { if kit.Int(kit.Select("0", arg, 1)) < 0 { NextPage(m, total, arg...) } else { - m.Toast("已经是最后一页啦!") - m.ProcessHold() + m.ProcessHold("已经是最后一页啦!") } } + +func OptionPages(m *ice.Message, arg ...string) (page int, size int) { + m.Option(CACHE_LIMIT, kit.Select("", arg, 0)) + m.Option(CACHE_OFFEND, kit.Select("", arg, 1)) + m.Option(CACHE_FILTER, kit.Select("", arg, 2)) + m.Option(LIMIT, kit.Select(m.Option(LIMIT), arg, 0)) + m.Option(OFFEND, kit.Select(m.Option(OFFEND), arg, 1)) + size = kit.Int(kit.Select("10", m.Option(LIMIT))) + page = kit.Int(m.Option(OFFEND))/size + 1 + return +} +func OptionPage(m *ice.Message, arg ...string) int { + page, _ := OptionPages(m, arg...) + return page +} + +const ( // CACHE + CACHE_LIMIT = "cache.limit" + CACHE_BEGIN = "cache.begin" + CACHE_COUNT = "cache.count" + CACHE_OFFEND = "cache.offend" + CACHE_FILTER = "cache.filter" + CACHE_VALUE = "cache.value" + CACHE_FIELD = "cache.field" +) + +func Grow(m *ice.Message, prefix string, chain Any, data Any) int { + cache := m.Confm(prefix, chain) + if cache == nil { + cache = kit.Data() + m.Confv(prefix, chain, cache) + } + return miss.Grow(path.Join(prefix, kit.Keys(chain)), cache, data) +} +func Grows(m *ice.Message, prefix string, chain Any, match string, value string, cb Any) Map { + cache := m.Confm(prefix, chain) + if cache == nil { + return nil + } + + limit := kit.Int(m.Option(CACHE_LIMIT)) + if begin := kit.Int(m.Option(CACHE_BEGIN)); begin != 0 && limit > 0 { + count := kit.Int(m.Option(CACHE_COUNT, kit.Int(kit.Value(cache, kit.Keym("count"))))) + if begin > 0 { + m.Option(CACHE_OFFEND, count-begin-limit) + } else { + m.Option(CACHE_OFFEND, -begin-limit) + } + } + + return miss.Grows(path.Join(prefix, kit.Keys(chain)), cache, + kit.Int(kit.Select("0", strings.TrimPrefix(m.Option(CACHE_OFFEND), "-"))), + kit.Int(kit.Select("10", m.Option(CACHE_LIMIT))), + match, value, cb) +} diff --git a/base/mdb/mdb.go b/base/mdb/mdb.go index 2165f111..7e14e27f 100644 --- a/base/mdb/mdb.go +++ b/base/mdb/mdb.go @@ -6,23 +6,32 @@ import ( ice "shylinux.com/x/icebergs" kit "shylinux.com/x/toolkits" + "shylinux.com/x/toolkits/task" ) type Any = interface{} type Map = map[string]Any type Maps = map[string]string -func _domain_chain(m *ice.Message, chain string) string { - return kit.Keys(m.Option(ice.MSG_DOMAIN), chain) -} func _file_name(m *ice.Message, arg ...string) string { if len(arg) > 3 && strings.Contains(arg[3], ice.PS) { return arg[3] } - return path.Join(ice.USR_LOCAL_EXPORT, m.Option(ice.MSG_DOMAIN), path.Join(arg[:2]...), arg[2]) + return path.Join(ice.USR_LOCAL_EXPORT, path.Join(arg[:2]...), arg[2]) } func _mdb_args(m *ice.Message, field string, arg ...Any) []string { - args := kit.Simple(arg...) + res := []Any{} + for _, v := range arg { + switch v := v.(type) { + case Map: + for k, v := range v { + m.Option(k, v) + } + default: + res = append(res, v) + } + } + args := kit.Simple(res...) for i := 0; i < len(args); i += 2 { if !strings.Contains(field, args[i]) && !strings.HasPrefix(args[i], EXTRA) { args[i] = kit.Keys(EXTRA, args[i]) @@ -39,29 +48,29 @@ func _mdb_modify(m *ice.Message, val ice.Map, field string, arg ...string) { kit.Value(val, arg[i], kit.Select("", arg, i+1)) } } -func _mdb_select(m *ice.Message, key string, value ice.Map, fields []string, val ice.Map) { - switch value = kit.GetMeta(value); cb := m.OptionCB(SELECT).(type) { - case func(string, []string, ice.Map, ice.Map): - cb(key, fields, value, val) - case func([]string, ice.Map): +func _mdb_select(m *ice.Message, cb Any, key string, value Map, fields []string, val Map) { + switch value = kit.GetMeta(value); cb := cb.(type) { + case func([]string, Map): cb(fields, value) - case func(string, ice.Map, ice.Map): + case func(string, []string, Map, Map): + cb(key, fields, value, val) + case func(string, Map, Map): cb(key, value, val) - case func(string, ice.Map): + case func(string, Map): cb(key, value) - case func(ice.Map): + case func(Map): cb(value) case func(Any): cb(value[TARGET]) - case func(ice.Maps): - res := ice.Maps{} + case func(Maps): + res := Maps{} for k, v := range value { res[k] = kit.Format(v) } cb(res) case nil: if m.FieldsIsDetail() { - m.Push(ice.CACHE_DETAIL, value) + m.Push(ice.FIELDS_DETAIL, value) } else { m.Push(key, value, fields, val) } @@ -168,11 +177,11 @@ var Index = &ice.Context{Name: MDB, Help: "数据模块", Commands: ice.Commands default: switch arg[2] { case ZONE: // inputs key sub type zone field value - _zone_inputs(m, arg[0], _domain_chain(m, arg[1]), arg[3], kit.Select(NAME, arg, 4), kit.Select("", arg, 5)) + _zone_inputs(m, arg[0], arg[1], arg[3], kit.Select(NAME, arg, 4), kit.Select("", arg, 5)) case HASH: - _hash_inputs(m, arg[0], _domain_chain(m, arg[1]), kit.Select(NAME, arg, 3), kit.Select("", arg, 4)) + _hash_inputs(m, arg[0], arg[1], kit.Select(NAME, arg, 3), kit.Select("", arg, 4)) case LIST: - _list_inputs(m, arg[0], _domain_chain(m, arg[1]), kit.Select(NAME, arg, 3), kit.Select("", arg, 4)) + _list_inputs(m, arg[0], arg[1], kit.Select(NAME, arg, 3), kit.Select("", arg, 4)) } } }}, @@ -180,11 +189,11 @@ var Index = &ice.Context{Name: MDB, Help: "数据模块", Commands: ice.Commands defer m.ProcessRefresh3ms() switch arg[2] { case ZONE: // insert key sub type zone arg... - _zone_insert(m, arg[0], _domain_chain(m, arg[1]), arg[3], arg[4:]...) + _zone_insert(m, arg[0], arg[1], arg[3], arg[4:]...) case HASH: - _hash_insert(m, arg[0], _domain_chain(m, arg[1]), arg[3:]...) + _hash_insert(m, arg[0], arg[1], arg[3:]...) case LIST: - _list_insert(m, arg[0], _domain_chain(m, arg[1]), arg[3:]...) + _list_insert(m, arg[0], arg[1], arg[3:]...) } }}, DELETE: {Name: "delete key sub type field value", Help: "删除", Hand: func(m *ice.Message, arg ...string) { @@ -193,29 +202,29 @@ var Index = &ice.Context{Name: MDB, Help: "数据模块", Commands: ice.Commands case ZONE: // delete key sub type zone field value // _list_delete(m, arg[0], _domain_chain(m, kit.Keys(arg[1], kit.KeyHash(arg[3]))), arg[4], arg[5]) case HASH: - _hash_delete(m, arg[0], _domain_chain(m, arg[1]), arg[3], arg[4]) + _hash_delete(m, arg[0], arg[1], arg[3], arg[4]) case LIST: - // _list_delete(m, arg[0], _domain_chain(m, arg[1]), arg[3], arg[4]) + // _list_delete(m, arg[0], arg[1], arg[3], arg[4]) } }}, MODIFY: {Name: "modify key sub type field value arg...", Help: "编辑", Hand: func(m *ice.Message, arg ...string) { switch arg[2] { case ZONE: // modify key sub type zone id field value - _zone_modify(m, arg[0], _domain_chain(m, arg[1]), arg[3], arg[4], arg[5:]...) + _zone_modify(m, arg[0], arg[1], arg[3], arg[4], arg[5:]...) case HASH: - _hash_modify(m, arg[0], _domain_chain(m, arg[1]), arg[3], arg[4], arg[5:]...) + _hash_modify(m, arg[0], arg[1], arg[3], arg[4], arg[5:]...) case LIST: - _list_modify(m, arg[0], _domain_chain(m, arg[1]), arg[3], arg[4], arg[5:]...) + _list_modify(m, arg[0], arg[1], arg[3], arg[4], arg[5:]...) } }}, SELECT: {Name: "select key sub type field value", Help: "查询", Hand: func(m *ice.Message, arg ...string) { switch arg[2] { case ZONE: - _zone_select(m, arg[0], _domain_chain(m, arg[1]), kit.Select("", arg, 3), kit.Select("", arg, 4)) + _zone_select(m, arg[0], arg[1], kit.Select("", arg, 3), kit.Select("", arg, 4)) case HASH: - _hash_select(m, arg[0], _domain_chain(m, arg[1]), kit.Select("", arg, 3), kit.Select(FOREACH, arg, 4)) + _hash_select(m, arg[0], arg[1], kit.Select("", arg, 3), kit.Select(FOREACH, arg, 4)) case LIST: - _list_select(m, arg[0], _domain_chain(m, arg[1]), kit.Select("", arg, 3), kit.Select("", arg, 4)) + _list_select(m, arg[0], arg[1], kit.Select("", arg, 3), kit.Select("", arg, 4)) } }}, PRUNES: {Name: "prunes key sub type [field value]...", Help: "清理", Hand: func(m *ice.Message, arg ...string) { @@ -223,35 +232,35 @@ var Index = &ice.Context{Name: MDB, Help: "数据模块", Commands: ice.Commands case ZONE: // prunes key sub type zone field value // _list_prunes(m, arg[0], _domain_chain(m, kit.Keys(arg[1], kit.KeyHash(arg[3]))), arg[4:]...) case HASH: - _hash_prunes(m, arg[0], _domain_chain(m, arg[1]), arg[3:]...) - m.Tables(func(value ice.Maps) { _hash_delete(m, arg[0], _domain_chain(m, arg[1]), HASH, value[HASH]) }) + _hash_prunes(m, arg[0], arg[1], arg[3:]...) + m.Tables(func(value ice.Maps) { _hash_delete(m, arg[0], arg[1], HASH, value[HASH]) }) case LIST: - // _list_prunes(m, arg[0], _domain_chain(m, arg[1]), arg[3:]...) + // _list_prunes(m, arg[0], arg[1], arg[3:]...) } }}, EXPORT: {Name: "export key sub type file", Help: "导出", Hand: func(m *ice.Message, arg ...string) { - if m.Option(ice.CACHE_LIMIT) == "" { - m.Option(ice.CACHE_LIMIT, "-1") + if m.Option(CACHE_LIMIT) == "" { + m.Option(CACHE_LIMIT, "-1") } switch file := _file_name(m, arg...); arg[2] { case ZONE: m.OptionFields(ZoneShort(m), m.Config(FIELD)) - _zone_export(m, arg[0], _domain_chain(m, arg[1]), file) + _zone_export(m, arg[0], arg[1], file) case HASH: - _hash_export(m, arg[0], _domain_chain(m, arg[1]), file) + _hash_export(m, arg[0], arg[1], file) case LIST: m.OptionFields(m.Config(FIELD)) - _list_export(m, arg[0], _domain_chain(m, arg[1]), file) + _list_export(m, arg[0], arg[1], file) } }}, IMPORT: {Name: "import key sub type file", Help: "导入", Hand: func(m *ice.Message, arg ...string) { switch file := _file_name(m, arg...); arg[2] { case ZONE: - _zone_import(m, arg[0], _domain_chain(m, arg[1]), file) + _zone_import(m, arg[0], arg[1], file) case HASH: - _hash_import(m, arg[0], _domain_chain(m, arg[1]), file) + _hash_import(m, arg[0], arg[1], file) case LIST: - _list_import(m, arg[0], _domain_chain(m, arg[1]), file) + _list_import(m, arg[0], arg[1], file) } }}, }} @@ -267,7 +276,7 @@ func AutoConfig(args ...ice.Any) *ice.Action { return &ice.Action{Hand: func(m *ice.Message, arg ...string) { if cs := m.Target().Configs; cs[m.CommandKey()] == nil && len(args) > 0 { cs[m.CommandKey()] = &ice.Config{Value: kit.Data(args...)} - m.Load(m.CommandKey()) + ice.Info.Load(m, m.CommandKey()) } inputs := []ice.Any{} @@ -295,3 +304,26 @@ func AutoConfig(args ...ice.Any) *ice.Action { } }} } + +var _locks = map[string]*task.Lock{} +var _lock = task.Lock{} + +func getLock(m *ice.Message, key string) *task.Lock { + if key == "" { + key = m.PrefixKey() + } + + defer _lock.Lock()() + l, ok := _locks[key] + if !ok { + l = &task.Lock{} + _locks[key] = l + } + return l +} +func RLock(m *ice.Message, arg ...ice.Any) func() { + return getLock(m, kit.Keys(arg...)).RLock() +} +func Lock(m *ice.Message, arg ...ice.Any) func() { + return getLock(m, kit.Keys(arg...)).Lock() +} diff --git a/base/mdb/render.go b/base/mdb/render.go index c4c0f102..1254193a 100644 --- a/base/mdb/render.go +++ b/base/mdb/render.go @@ -21,7 +21,7 @@ func RenderAction(args ...ice.Any) ice.Actions { CREATE: {Name: "create type name text", Help: "创建", Hand: func(m *ice.Message, arg ...string) { m.Option(TYPE, kit.Ext(m.Option(TYPE))) m.Option(NAME, kit.Select(m.Option(TYPE), m.Option(NAME))) - m.Cmdy(INSERT, m.PrefixKey(), "", HASH, m.OptionSimple("type,name,text")) + m.Cmdy(INSERT, m.PrefixKey(), "", HASH, m.OptionSimple(TYPE, NAME, TEXT)) }}, SELECT: {Name: "select type name text auto", Help: "渲染", Hand: func(m *ice.Message, arg ...string) { if len(arg) > 1 { diff --git a/base/mdb/search.go b/base/mdb/search.go index 33dc9322..4f3e5fda 100644 --- a/base/mdb/search.go +++ b/base/mdb/search.go @@ -2,6 +2,7 @@ package mdb import ( ice "shylinux.com/x/icebergs" + kit "shylinux.com/x/toolkits" ) const SEARCH = "search" @@ -9,3 +10,31 @@ const SEARCH = "search" func init() { Index.MergeCommands(ice.Commands{SEARCH: {Name: "search type name text auto", Help: "搜索", Actions: RenderAction()}}) } +func SearchAction() ice.Actions { + return ice.Actions{ + SEARCH: {Name: "search type name text", Help: "搜索", Hand: func(m *ice.Message, arg ...string) { HashSelectSearch(m, arg) }}, + } +} +func HashSearchAction(arg ...Any) ice.Actions { + return ice.MergeAction(HashAction(arg...), SearchAction()) +} +func HashSelectSearch(m *ice.Message, args []string, keys ...string) *ice.Message { + if len(keys) == 0 { + ls := kit.Split(m.Config(FIELD)) + for _, k := range ls { + switch k { + case TIME, HASH: + default: + keys = append(keys, k) + } + } + } + if args[0] == m.CommandKey() { + HashSelectValue(m, func(value ice.Map) { + if args[1] == "" || args[1] == value[keys[1]] { + m.PushSearch(kit.SimpleKV("", value[keys[0]], value[keys[1]], value[keys[2]]), value) + } + }) + } + return m +} diff --git a/base/mdb/zone.go b/base/mdb/zone.go index 60a3e26f..d866a768 100644 --- a/base/mdb/zone.go +++ b/base/mdb/zone.go @@ -18,24 +18,24 @@ func _zone_inputs(m *ice.Message, prefix, chain, zone string, field, value strin _hash_inputs(m, prefix, chain, field, value) return } - h := _hash_select_fields(m, prefix, chain, zone, HASH) - defer m.RLock(prefix, chain)() - _list_inputs(m, prefix, _domain_chain(m, kit.Keys(chain, HASH, h)), field, value) + h := _hash_select_field(m, prefix, chain, zone, HASH) + defer RLock(m, prefix, chain)() + _list_inputs(m, prefix, kit.Keys(chain, HASH, h), field, value) } func _zone_insert(m *ice.Message, prefix, chain, zone string, arg ...string) { - h := _hash_select_fields(m, prefix, chain, zone, HASH) + h := _hash_select_field(m, prefix, chain, zone, HASH) if h == "" { h = _hash_insert(m, prefix, chain, m.Conf(prefix, kit.Keys(chain, kit.Keym(SHORT))), zone) } m.Assert(h != "") - defer m.Lock(prefix, chain)() - _list_insert(m, prefix, _domain_chain(m, kit.Keys(chain, HASH, h)), arg...) + defer Lock(m, prefix, chain)() + _list_insert(m, prefix, kit.Keys(chain, HASH, h), arg...) } func _zone_modify(m *ice.Message, prefix, chain, zone, id string, arg ...string) { - h := _hash_select_fields(m, prefix, chain, zone, HASH) + h := _hash_select_field(m, prefix, chain, zone, HASH) m.Assert(h != "") - defer m.RLock(prefix, chain)() - _list_modify(m, prefix, _domain_chain(m, kit.Keys(chain, HASH, h)), ID, id, arg...) + defer RLock(m, prefix, chain)() + _list_modify(m, prefix, kit.Keys(chain, HASH, h), ID, id, arg...) } func _zone_select(m *ice.Message, prefix, chain, zone string, id string) { if zone == "" { @@ -47,12 +47,12 @@ func _zone_select(m *ice.Message, prefix, chain, zone string, id string) { } fields := _zone_fields(m) - defer m.RLock(prefix, chain)() - m.Richs(prefix, chain, kit.Select(FOREACH, zone), func(key string, val Map) { + defer RLock(m, prefix, chain)() + Richs(m, prefix, chain, kit.Select(FOREACH, zone), func(key string, val Map) { chain := kit.Keys(chain, HASH, key) - defer m.RLock(prefix, chain)() - m.Grows(prefix, chain, ID, id, func(value ice.Map) { - _mdb_select(m, key, value, fields, val) + defer RLock(m, prefix, chain)() + Grows(m, prefix, chain, ID, id, func(value ice.Map) { + _mdb_select(m, m.OptionCB(""), key, value, fields, val) }) }) } @@ -71,18 +71,18 @@ func _zone_export(m *ice.Message, prefix, chain, file string) { w.Write(fields) keys := []string{} - m.Richs(prefix, chain, FOREACH, func(key string, val ice.Map) { keys = append(keys, key) }) + Richs(m, prefix, chain, FOREACH, func(key string, val ice.Map) { keys = append(keys, key) }) kit.Sort(keys) count := 0 - defer m.Lock(prefix, chain)() + defer Lock(m, prefix, chain)() for _, key := range keys { - m.Richs(prefix, chain, key, func(key string, val ice.Map) { + Richs(m, prefix, chain, key, func(key string, val ice.Map) { val = kit.GetMeta(val) chain := kit.Keys(chain, HASH, key) - defer m.RLock(prefix, chain)() - m.Grows(prefix, chain, "", "", func(value ice.Map) { + defer RLock(m, prefix, chain)() + Grows(m, prefix, chain, "", "", func(value ice.Map) { value = kit.GetMeta(value) list := []string{} @@ -95,7 +95,7 @@ func _zone_export(m *ice.Message, prefix, chain, file string) { }) } - m.Log_EXPORT(KEY, path.Join(prefix, chain), FILE, p, COUNT, count) + m.Logs(EXPORT, KEY, path.Join(prefix, chain), FILE, p, COUNT, count) m.Conf(prefix, kit.Keys(chain, HASH), "") m.Echo(p) } @@ -111,7 +111,7 @@ func _zone_import(m *ice.Message, prefix, chain, file string) { list := ice.Maps{} zkey := kit.Select(head[0], m.OptionFields()) - defer m.Lock(prefix, chain)() + defer Lock(m, prefix, chain)() for { line, e := r.Read() if e != nil { @@ -133,18 +133,18 @@ func _zone_import(m *ice.Message, prefix, chain, file string) { } } if list[zone] == "" { - list[zone] = m.Rich(prefix, chain, kit.Data(zkey, zone)) + list[zone] = Rich(m, prefix, chain, kit.Data(zkey, zone)) } func() { chain := kit.Keys(chain, HASH, list[zone]) - defer m.Lock(prefix, chain)() - m.Grow(prefix, chain, data) + defer Lock(m, prefix, chain)() + Grow(m, prefix, chain, data) }() count++ } - m.Log_IMPORT(KEY, path.Join(prefix, chain), COUNT, count) + m.Logs(IMPORT, KEY, path.Join(prefix, chain), COUNT, count) m.Echo("%d", count) } @@ -155,36 +155,16 @@ const ZONE = "zone" func ZoneAction(args ...ice.Any) ice.Actions { return ice.Actions{ice.CTX_INIT: AutoConfig(args...), - INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) { - ZoneInputs(m, arg) - }}, - CREATE: {Name: "create zone", Help: "创建", Hand: func(m *ice.Message, arg ...string) { - ZoneCreate(m, arg) - }}, - REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) { - ZoneRemove(m, arg) - }}, - INSERT: {Name: "insert", Help: "添加", Hand: func(m *ice.Message, arg ...string) { - ZoneInsert(m, arg) - }}, - MODIFY: {Name: "modify", Help: "编辑", Hand: func(m *ice.Message, arg ...string) { - ZoneModify(m, arg) - }}, - SELECT: {Name: "select", Help: "列表", Hand: func(m *ice.Message, arg ...string) { - ZoneSelect(m, arg...) - }}, - EXPORT: {Name: "export", Help: "导出", Hand: func(m *ice.Message, arg ...string) { - ZoneExport(m, arg) - }}, - IMPORT: {Name: "import", Help: "导入", Hand: func(m *ice.Message, arg ...string) { - ZoneImport(m, arg) - }}, - PREV: {Name: "prev", Help: "上一页", Hand: func(m *ice.Message, arg ...string) { - PrevPage(m, arg[0], arg[1:]...) - }}, - NEXT: {Name: "next", Help: "下一页", Hand: func(m *ice.Message, arg ...string) { - NextPageLimit(m, arg[0], arg[1:]...) - }}, + INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) { ZoneInputs(m, arg) }}, + CREATE: {Name: "create zone", Help: "创建", Hand: func(m *ice.Message, arg ...string) { ZoneCreate(m, arg) }}, + REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) { ZoneRemove(m, arg) }}, + INSERT: {Name: "insert", Help: "添加", Hand: func(m *ice.Message, arg ...string) { ZoneInsert(m, arg) }}, + MODIFY: {Name: "modify", Help: "编辑", Hand: func(m *ice.Message, arg ...string) { ZoneModify(m, arg) }}, + SELECT: {Name: "select", Help: "列表", Hand: func(m *ice.Message, arg ...string) { ZoneSelect(m, arg...) }}, + EXPORT: {Name: "export", Help: "导出", Hand: func(m *ice.Message, arg ...string) { ZoneExport(m, arg) }}, + IMPORT: {Name: "import", Help: "导入", Hand: func(m *ice.Message, arg ...string) { ZoneImport(m, arg) }}, + PREV: {Name: "prev", Help: "上一页", Hand: func(m *ice.Message, arg ...string) { PrevPage(m, arg[0], arg[1:]...) }}, + NEXT: {Name: "next", Help: "下一页", Hand: func(m *ice.Message, arg ...string) { NextPageLimit(m, arg[0], arg[1:]...) }}, } } func ZoneShort(m *ice.Message) string { @@ -221,7 +201,7 @@ func ZoneSelect(m *ice.Message, arg ...string) *ice.Message { m.PushAction(m.Config(ACTION), REMOVE) m.StatusTimeCount() } else if len(arg) == 1 { - m.StatusTimeCountTotal(m.Conf("", kit.Keys(HASH, HashSelectFields(m, arg[0], HASH), kit.Keym(COUNT)))) + m.StatusTimeCountTotal(m.Conf("", kit.Keys(HASH, HashSelectField(m, arg[0], HASH), kit.Keym(COUNT)))) } return m } @@ -232,15 +212,15 @@ func ZoneImport(m *ice.Message, arg ...Any) { m.Cmdy(IMPORT, m.PrefixKey(), "", ZONE, arg) } func ZoneSelectPage(m *ice.Message, arg ...string) *ice.Message { - m.OptionPages(kit.Slice(arg, 2)...) + OptionPages(m, kit.Slice(arg, 2)...) return ZoneSelect(m, arg...) } func ZoneSelectAll(m *ice.Message, arg ...string) *ice.Message { - m.Option(ice.CACHE_LIMIT, "-1") + m.Option(CACHE_LIMIT, "-1") return ZoneSelect(m, arg...) } -func ZoneSelectCB(m *ice.Message, zone string, cb ice.Any) *ice.Message { +func ZoneSelectCB(m *ice.Message, zone string, cb Any) *ice.Message { m.OptionCB(SELECT, cb) - m.Option(ice.CACHE_LIMIT, "-1") + m.Option(CACHE_LIMIT, "-1") return ZoneSelect(m, zone) } diff --git a/base/nfs/cat.go b/base/nfs/cat.go index 8bd460b6..5df4fa38 100644 --- a/base/nfs/cat.go +++ b/base/nfs/cat.go @@ -3,11 +3,14 @@ package nfs import ( "bufio" "bytes" + "encoding/json" "io" "path" "strings" ice "shylinux.com/x/icebergs" + "shylinux.com/x/icebergs/base/aaa" + "shylinux.com/x/icebergs/base/mdb" kit "shylinux.com/x/toolkits" ) @@ -34,7 +37,7 @@ func _cat_hash(m *ice.Message, p string) string { return "" } func _cat_list(m *ice.Message, name string) { - if !m.Right(m, name) { + if !aaa.Right(m, name) { return // 没有权限 } f, e := _cat_find(m, name) @@ -43,7 +46,7 @@ func _cat_list(m *ice.Message, name string) { } defer f.Close() - switch cb := m.OptionCB(CAT).(type) { + switch cb := m.OptionCB("").(type) { case func(string, int) string: list := []string{} for bio, i := bufio.NewScanner(f), 0; bio.Scan(); i++ { @@ -69,7 +72,7 @@ func _cat_list(m *ice.Message, name string) { buf, begin := make([]byte, ice.MOD_BUFS), 0 for { if n, e := f.Read(buf[begin:]); !m.Warn(e, ice.ErrNotValid, name) { - m.Log_IMPORT(FILE, name, SIZE, n) + m.Logs(mdb.IMPORT, FILE, name, SIZE, n) if begin += n; begin < len(buf) { buf = buf[:begin] break @@ -87,21 +90,18 @@ func _cat_list(m *ice.Message, name string) { const ( CAT_CONTENT = "cat_content" - TEMPLATE = "template" - WEBSITE = "website" STDIO = "stdio" SOURCE = "source" SCRIPT = "script" BINARY = "binary" TARGET = "target" + TAGS = "tags" - MASTER = "master" - BRANCH = "branch" - REPOS = "repos" - - LOAD = "load" - TAGS = "tags" + TEMPLATE = "template" + MASTER = "master" + BRANCH = "branch" + REPOS = "repos" ) const ( HTML = ice.HTML @@ -115,6 +115,7 @@ const ( JSON = ice.JSON PY = "py" + MD = "md" TXT = "txt" IML = "iml" XML = "xml" @@ -124,6 +125,7 @@ const ( PNG = "png" JPG = "jpg" MP4 = "mp4" + PDF = "pdf" PWD = "./" PS = ice.PS @@ -137,9 +139,8 @@ func init() { CAT: {Name: CAT, Help: "文件", Value: kit.Data( SOURCE, kit.Dict( HTML, ice.TRUE, CSS, ice.TRUE, JS, ice.TRUE, GO, ice.TRUE, SH, ice.TRUE, CSV, ice.TRUE, JSON, ice.TRUE, - "md", ice.TRUE, "shy", ice.TRUE, "makefile", ice.TRUE, "license", ice.TRUE, - "conf", ice.TRUE, YML, ice.TRUE, ZML, ice.TRUE, IML, ice.TRUE, "txt", ice.TRUE, - "py", ice.TRUE, + SHY, ice.TRUE, "conf", ice.TRUE, "makefile", ice.TRUE, "license", ice.TRUE, + PY, ice.TRUE, MD, ice.TRUE, TXT, ice.TRUE, IML, ice.TRUE, XML, ice.TRUE, YML, ice.TRUE, ZML, ice.TRUE, ), )}, }, Commands: ice.Commands{ @@ -149,9 +150,22 @@ func init() { return } if m.Option(DIR_ROOT) != "" { - m.Log_SELECT(DIR_ROOT, m.Option(DIR_ROOT)) + m.Logs(mdb.SELECT, DIR_ROOT, m.Option(DIR_ROOT)) } _cat_list(m, arg[0]) }}, }}) } +func OptionLoad(m *ice.Message, file string) *ice.Message { + if f, e := OpenFile(m, file); e == nil { + defer f.Close() + + var data ice.Any + m.Assert(json.NewDecoder(f).Decode(&data)) + + kit.Fetch(data, func(key string, value ice.Any) { + m.Option(key, kit.Simple(value)) + }) + } + return m +} diff --git a/base/nfs/dir.go b/base/nfs/dir.go index 251fee41..73d38da2 100644 --- a/base/nfs/dir.go +++ b/base/nfs/dir.go @@ -29,7 +29,7 @@ func _dir_hash(m *ice.Message, p string) string { return "" } func _dir_list(m *ice.Message, root string, name string, level int, deep bool, dir_type string, dir_reg *regexp.Regexp, fields []string) *ice.Message { - if !m.Right(m, path.Join(root, name)) { + if !aaa.Right(m, path.Join(root, name)) { return m // 没有权限 } @@ -55,7 +55,7 @@ func _dir_list(m *ice.Message, root string, name string, level int, deep bool, d p, pp := path.Join(root, name, f.Name()), path.Join(name, f.Name()) isDir := f.IsDir() || kit.IsDir(p) if !(dir_type == TYPE_CAT && isDir || dir_type == TYPE_DIR && !isDir) && (dir_reg == nil || dir_reg.MatchString(f.Name())) { - switch cb := m.OptionCB(DIR).(type) { + switch cb := m.OptionCB("").(type) { case func(f os.FileInfo, p string): cb(f, p) continue @@ -108,12 +108,11 @@ func _dir_list(m *ice.Message, root string, name string, level int, deep bool, d } else { h = _cat_hash(m, p) } - m.Debug("what %v %v", h, p) m.Push(mdb.HASH, kit.Select(h[:6], h[:], field == mdb.HASH)) case mdb.LINK: m.PushDownload(mdb.LINK, kit.Select("", f.Name(), !isDir), p) case mdb.SHOW: - switch p := m.MergeURL2("/share/local/"+p, ice.POD, m.Option(ice.MSG_USERPOD)); kit.Ext(f.Name()) { + switch p := kit.MergeURL("/share/local/"+p, ice.POD, m.Option(ice.MSG_USERPOD)); kit.Ext(f.Name()) { case PNG, JPG: m.PushImages(field, p) case MP4: @@ -122,7 +121,7 @@ func _dir_list(m *ice.Message, root string, name string, level int, deep bool, d m.Push(field, "") } case mdb.ACTION: - if m.IsCliUA() || m.Option(ice.MSG_USERROLE) == aaa.VOID { + if m.IsCliUA() || m.Option(ice.MSG_USERROLE) == "void" { break } m.PushButton(TRASH) @@ -176,14 +175,14 @@ func init() { Index.MergeCommands(ice.Commands{ DIR: {Name: "dir path field auto upload", Help: "目录", Actions: ice.Actions{ mdb.UPLOAD: {Name: "upload", Help: "上传", Hand: func(m *ice.Message, arg ...string) { - m.Upload(m.Option(PATH)) + m.Cmdy("web.cache", "upload_watch", m.Option(PATH)) }}, TRASH: {Name: "trash", Help: "删除", Hand: func(m *ice.Message, arg ...string) { m.Cmdy(TRASH, m.Option(PATH)) }}, }, Hand: func(m *ice.Message, arg ...string) { if m.Option(DIR_ROOT) != "" { - m.Log_SELECT(DIR_ROOT, m.Option(DIR_ROOT)) + m.Logs(mdb.SELECT, DIR_ROOT, m.Option(DIR_ROOT)) } _dir_list(m, kit.Select(PWD, m.Option(DIR_ROOT)), kit.Select(PWD, arg, 0), 0, m.Option(DIR_DEEP) == ice.TRUE, kit.Select(TYPE_BOTH, m.Option(DIR_TYPE)), kit.Regexp(m.Option(DIR_REG)), @@ -197,7 +196,6 @@ func init() { func Dir(m *ice.Message, sort string) *ice.Message { m.Option(DIR_TYPE, TYPE_DIR) m.Copy(m.Cmd(DIR, PWD).Sort(sort)) - m.Option(DIR_TYPE, TYPE_CAT) m.Copy(m.Cmd(DIR, PWD).Sort(sort)) return m diff --git a/base/nfs/nfs.go b/base/nfs/nfs.go index 173c51a8..b4caa6af 100644 --- a/base/nfs/nfs.go +++ b/base/nfs/nfs.go @@ -1,107 +1,9 @@ package nfs -import ( - "io" - "io/ioutil" - "os" - - ice "shylinux.com/x/icebergs" - "shylinux.com/x/toolkits/file" -) +import ice "shylinux.com/x/icebergs" var Index = &ice.Context{Name: "nfs", Help: "存储模块"} func init() { - ice.Index.Register(Index, nil, TAR, CAT, DIR, DEFS, SAVE, PUSH, COPY, LINK, TAIL, TRASH, GREP) -} - -var DiskFile = file.NewDiskFile() -var PackFile = file.NewPackFile() - -func init() { file.Init(ice.Pulse.OptionFiles(DiskFile, PackFile)) } - -func StatFile(m *ice.Message, p string) (os.FileInfo, error) { - file := m.OptionFiles() - return file.StatFile(p) -} -func OpenFile(m *ice.Message, p string) (io.ReadCloser, error) { - file := m.OptionFiles() - return file.OpenFile(p) -} -func CreateFile(m *ice.Message, p string) (io.WriteCloser, string, error) { - file := m.OptionFiles() - return file.CreateFile(p) -} -func AppendFile(m *ice.Message, p string) (io.ReadWriteCloser, string, error) { - file := m.OptionFiles() - w, e := file.AppendFile(p) - return w, p, e -} -func WriteFile(m *ice.Message, p string, b []byte) error { - file := m.OptionFiles() - return file.WriteFile(p, b) -} - -func ReadDir(m *ice.Message, p string) ([]os.FileInfo, error) { - file := m.OptionFiles() - list, e := file.ReadDir(p) - for i := 0; i < len(list)-1; i++ { - for j := i + 1; j < len(list); j++ { - if list[i].Name() > list[j].Name() { - list[i], list[j] = list[j], list[i] - } - } - } - return list, e -} -func MkdirAll(m *ice.Message, p string) error { - file := m.OptionFiles() - return file.MkdirAll(p, ice.MOD_DIR) -} -func RemoveAll(m *ice.Message, p string) error { - file := m.OptionFiles() - return file.RemoveAll(p) -} -func Remove(m *ice.Message, p string) error { - file := m.OptionFiles() - return file.Remove(p) -} -func Rename(m *ice.Message, oldname string, newname string) error { - file := m.OptionFiles() - return file.Rename(oldname, newname) -} -func Symlink(m *ice.Message, oldname string, newname string) error { - file := m.OptionFiles() - return file.Symlink(oldname, newname) -} -func Link(m *ice.Message, oldname string, newname string) error { - file := m.OptionFiles() - return file.Link(oldname, newname) -} -func Close(m *ice.Message) { - file := m.OptionFiles() - file.Close() -} - -func ExistsFile(m *ice.Message, p string) bool { - file := m.OptionFiles() - if _, e := file.StatFile(p); e == nil { - return true - } - return false -} -func ReadFile(m *ice.Message, p string) ([]byte, error) { - file := m.OptionFiles() - if f, e := file.OpenFile(p); e == nil { - return ioutil.ReadAll(f) - } else { - return nil, e - } -} - -func NewWriteCloser(w func([]byte) (int, error), c func() error) io.WriteCloser { - return file.NewWriteCloser(w, c) -} -func NewReadCloser(r io.Reader) io.ReadCloser { - return file.NewReadCloser(r) + ice.Index.Register(Index, nil, TAR, CAT, DIR, PACK, DEFS, SAVE, PUSH, COPY, LINK, TAIL, TRASH, GREP) } diff --git a/base/nfs/pack.go b/base/nfs/pack.go index 36262808..e2387195 100644 --- a/base/nfs/pack.go +++ b/base/nfs/pack.go @@ -3,12 +3,14 @@ package nfs import ( "io" "io/ioutil" + "os" "path" "strings" ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/mdb" kit "shylinux.com/x/toolkits" + "shylinux.com/x/toolkits/file" ) const PACK = "pack" @@ -22,16 +24,18 @@ func init() { defer b.Close() if f, p, e := pack.CreateFile(path.Join(m.Option(PATH), h.Filename)); m.Assert(e) { defer f.Close() - if n, e := io.Copy(f, b); e == nil { - m.Log_IMPORT(FILE, p, SIZE, n) + if n, e := io.Copy(f, b); m.Assert(e) { + m.Logs(mdb.EXPORT, FILE, p, SIZE, n) } } } }}, mdb.CREATE: {Name: "create path=h1/h2/hi.txt text=hello", Help: "创建", Hand: func(m *ice.Message, arg ...string) { - if f, _, e := pack.CreateFile(m.Option(PATH)); e == nil { + if f, p, e := pack.CreateFile(m.Option(PATH)); m.Assert(e) { defer f.Close() - f.Write([]byte(m.Option(mdb.TEXT))) + if n, e := f.Write([]byte(m.Option(mdb.TEXT))); m.Assert(e) { + m.Logs(mdb.EXPORT, FILE, p, SIZE, n) + } } }}, mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) { @@ -53,7 +57,7 @@ func init() { for _, f := range ls { m.Push(mdb.TIME, f.ModTime().Format(ice.MOD_TIME)) m.Push(PATH, path.Join(p, f.Name())+kit.Select("", PS, f.IsDir())) - m.Push(SIZE, f.Size()) + m.Push(SIZE, kit.FmtSize(f.Size())) } m.Sort("time,path") m.PushAction(mdb.REMOVE) @@ -61,3 +65,103 @@ func init() { }}, }) } + +var PackFile = file.NewPackFile() +var DiskFile = file.NewDiskFile() + +func init() { file.Init(OptionFiles(ice.Pulse, DiskFile, PackFile)) } + +func OptionFiles(m *ice.Message, f ...file.File) file.File { + if len(f) > 1 { + m.Optionv(ice.MSG_FILES, file.NewMultiFile(f...)) + } else if len(f) > 0 { + m.Optionv(ice.MSG_FILES, f[0]) + } + return m.Optionv(ice.MSG_FILES).(file.File) +} +func StatFile(m *ice.Message, p string) (os.FileInfo, error) { + return OptionFiles(m).StatFile(p) +} +func OpenFile(m *ice.Message, p string) (io.ReadCloser, error) { + return OptionFiles(m).OpenFile(p) +} +func CreateFile(m *ice.Message, p string) (io.WriteCloser, string, error) { + return OptionFiles(m).CreateFile(p) +} +func AppendFile(m *ice.Message, p string) (io.ReadWriteCloser, string, error) { + file := OptionFiles(m) + w, e := file.AppendFile(p) + return w, p, e +} +func WriteFile(m *ice.Message, p string, b []byte) error { + return OptionFiles(m).WriteFile(p, b) +} + +func ReadDir(m *ice.Message, p string) ([]os.FileInfo, error) { + list, e := OptionFiles(m).ReadDir(p) + for i := 0; i < len(list)-1; i++ { + for j := i + 1; j < len(list); j++ { + if list[i].Name() > list[j].Name() { + list[i], list[j] = list[j], list[i] + } + } + } + return list, e +} +func MkdirAll(m *ice.Message, p string) error { + return OptionFiles(m).MkdirAll(p, ice.MOD_DIR) +} +func RemoveAll(m *ice.Message, p string) error { + return OptionFiles(m).RemoveAll(p) +} +func Remove(m *ice.Message, p string) error { + return OptionFiles(m).Remove(p) +} +func Rename(m *ice.Message, oldname string, newname string) error { + return OptionFiles(m).Rename(oldname, newname) +} +func Symlink(m *ice.Message, oldname string, newname string) error { + return OptionFiles(m).Symlink(oldname, newname) +} +func Link(m *ice.Message, oldname string, newname string) error { + return OptionFiles(m).Link(oldname, newname) +} + +func ExistsFile(m *ice.Message, p string) bool { + if _, e := OptionFiles(m).StatFile(p); e == nil { + return true + } + return false +} +func ReadFile(m *ice.Message, p string) ([]byte, error) { + if f, e := OptionFiles(m).OpenFile(p); e == nil { + defer f.Close() + return ioutil.ReadAll(f) + } else { + return nil, e + } +} +func CloseFile(m *ice.Message, p ice.Any) { + if w, ok := p.(io.Closer); ok { + w.Close() + } +} + +func CopyFile(m *ice.Message, to io.WriteCloser, from io.ReadCloser, cb func(int)) { + buf := make([]byte, ice.MOD_BUFS) + for { + n, e := from.Read(buf) + if e != nil { + break + } + to.Write(buf[:n]) + cb(n) + } +} + +func NewWriteCloser(w func([]byte) (int, error), c func() error) io.WriteCloser { + return file.NewWriteCloser(w, c) +} +func NewReadCloser(r io.Reader) io.ReadCloser { + return file.NewReadCloser(r) +} diff --git a/base/nfs/save.go b/base/nfs/save.go index cd52f049..de3c0968 100644 --- a/base/nfs/save.go +++ b/base/nfs/save.go @@ -6,6 +6,7 @@ import ( "path" ice "shylinux.com/x/icebergs" + "shylinux.com/x/icebergs/base/mdb" kit "shylinux.com/x/toolkits" ) @@ -25,7 +26,7 @@ func _save_file(m *ice.Message, name string, text ...string) { for _, v := range text { if n, e := fmt.Fprint(f, v); m.Assert(e) { - m.Log_EXPORT(FILE, p, SIZE, n) + m.Logs(mdb.EXPORT, FILE, p, SIZE, n) } } m.Echo(p) @@ -37,7 +38,7 @@ func _push_file(m *ice.Message, name string, text ...string) { for _, k := range text { if n, e := fmt.Fprint(f, k); m.Assert(e) { - m.Log_EXPORT(FILE, p, SIZE, n) + m.Logs(mdb.EXPORT, FILE, p, SIZE, n) } } m.Echo(p) @@ -52,8 +53,8 @@ func _copy_file(m *ice.Message, name string, from ...string) { defer s.Close() if n, e := io.Copy(f, s); !m.Warn(e, ice.ErrNotFound, name) { - m.Log_IMPORT(FILE, v, SIZE, n) - m.Log_EXPORT(FILE, p, SIZE, n) + m.Logs(mdb.IMPORT, FILE, v, SIZE, n) + m.Logs(mdb.EXPORT, FILE, p, SIZE, n) } } } @@ -76,7 +77,7 @@ func _link_file(m *ice.Message, name string, from string) { return } } - m.Log_EXPORT(FILE, name, FROM, from) + m.Logs(mdb.CREATE, FILE, name, FROM, from) m.Echo(name) } @@ -109,7 +110,7 @@ func init() { }}, COPY: {Name: "copy file from...", Help: "复制", Hand: func(m *ice.Message, arg ...string) { for _, file := range arg[1:] { - if kit.FileExists(file) { + if ExistsFile(m, file) { _copy_file(m, arg[0], arg[1:]...) return } diff --git a/base/nfs/tail.go b/base/nfs/tail.go index 5252663b..2183cd96 100644 --- a/base/nfs/tail.go +++ b/base/nfs/tail.go @@ -17,8 +17,8 @@ func _tail_create(m *ice.Message, arg ...string) { r, w := io.Pipe() m.Go(func() { for bio := bufio.NewScanner(r); bio.Scan(); { - m.Log_IMPORT(FILE, file, SIZE, len(bio.Text())) - m.Grow(TAIL, kit.Keys(mdb.HASH, h), kit.Dict( + m.Logs(mdb.IMPORT, FILE, file, SIZE, len(bio.Text())) + mdb.Grow(m, TAIL, kit.Keys(mdb.HASH, h), kit.Dict( FILE, file, SIZE, len(bio.Text()), mdb.TEXT, bio.Text(), )) } @@ -39,7 +39,7 @@ func init() { Index.MergeCommands(ice.Commands{ TAIL: {Name: "tail name id auto page filter:text create", Help: "日志流", Actions: ice.MergeAction(ice.Actions{ ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { - m.Richs(TAIL, "", mdb.FOREACH, func(key string, value ice.Map) { + mdb.Richs(m, TAIL, "", mdb.FOREACH, func(key string, value ice.Map) { value, _ = kit.GetMeta(value), m.Option(mdb.HASH, key) m.Cmd(TAIL, mdb.CREATE, kit.SimpleKV("file,name", value)) }) @@ -60,10 +60,10 @@ func init() { }}, }, mdb.ZoneAction(mdb.SHORT, mdb.NAME, mdb.FIELD, "time,id,file,text")), Hand: func(m *ice.Message, arg ...string) { m.Fields(len(kit.Slice(arg, 0, 2)), "time,name,count,file", m.Config(mdb.FIELD)) - m.OptionPage(kit.Slice(arg, 2)...) + mdb.OptionPage(m, kit.Slice(arg, 2)...) mdb.ZoneSelect(m.Spawn(), arg...).Table(func(index int, value ice.Maps, head []string) { - if strings.Contains(value[mdb.TEXT], m.Option(ice.CACHE_FILTER)) { + if strings.Contains(value[mdb.TEXT], m.Option(mdb.CACHE_FILTER)) { m.Push("", value, head) } }) diff --git a/base/nfs/tar.go b/base/nfs/tar.go index bfd5c773..114e85dc 100644 --- a/base/nfs/tar.go +++ b/base/nfs/tar.go @@ -73,13 +73,11 @@ func init() { } defer file.Close() - m.PushNoticeGrow(kit.Format("%v %v %v\n", header.Name, kit.FmtSize(f.Size()), kit.FmtSize(total))) if _, err = io.Copy(t, file); m.Warn(err) { return } count++ - m.Toast(kit.Format("%v %v %v", count, m.Cost(), kit.FmtSize(total))) }) } m.StatusTimeCountTotal(kit.FmtSize(total)) diff --git a/base/nfs/trash.go b/base/nfs/trash.go index 8c291eac..323af83f 100644 --- a/base/nfs/trash.go +++ b/base/nfs/trash.go @@ -53,7 +53,7 @@ func init() { mdb.PRUNES: {Name: "prunes before@date", Help: "清理", Hand: func(m *ice.Message, arg ...string) { mdb.HashPrunes(m, func(value ice.Maps) bool { Remove(m, value[FILE]) - return false + return true }) }}, }, mdb.HashAction(mdb.SHORT, FROM, mdb.FIELD, "time,hash,file,from")), Hand: func(m *ice.Message, arg ...string) { diff --git a/base/ssh/render.go b/base/ssh/render.go new file mode 100644 index 00000000..6fe6f8c0 --- /dev/null +++ b/base/ssh/render.go @@ -0,0 +1,31 @@ +package ssh + +import ( + "fmt" + "strings" + + ice "shylinux.com/x/icebergs" + kit "shylinux.com/x/toolkits" +) + +func Render(msg *ice.Message, cmd string, arg ...ice.Any) (res string) { + switch args := kit.Simple(arg...); cmd { + case ice.RENDER_RESULT: + if len(args) > 0 { + msg.Resultv(args) + } + res = msg.Result() + + case ice.RENDER_VOID: + return res + + default: + if res = msg.Result(); res == "" { + res = msg.Table().Result() + } + } + if fmt.Fprint(msg.O, res); !strings.HasSuffix(res, ice.NL) { + fmt.Fprint(msg.O, ice.NL) + } + return res +} diff --git a/base/ssh/scripts.go b/base/ssh/scripts.go index a42a2c0c..0b643815 100644 --- a/base/ssh/scripts.go +++ b/base/ssh/scripts.go @@ -13,32 +13,11 @@ import ( ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/cli" "shylinux.com/x/icebergs/base/ctx" - "shylinux.com/x/icebergs/base/gdb" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" kit "shylinux.com/x/toolkits" ) -func Render(msg *ice.Message, cmd string, arg ...ice.Any) (res string) { - switch args := kit.Simple(arg...); cmd { - case ice.RENDER_VOID: - return res - case ice.RENDER_RESULT: - if len(args) > 0 { - msg.Resultv(args) - } - res = msg.Result() - default: - if res = msg.Result(); res == "" { - res = msg.Table().Result() - } - } - if fmt.Fprint(msg.O, res); !strings.HasSuffix(res, ice.NL) { - fmt.Fprint(msg.O, ice.NL) - } - return res -} - type Frame struct { source string target *ice.Context @@ -94,7 +73,7 @@ func (f *Frame) change(m *ice.Message, ls []string) []string { target = "" } m.Spawn(f.target).Search(target+ice.PT, func(p *ice.Context, s *ice.Context, key string) { - m.Log_SELECT(ctx.CONTEXT, s.Name) + m.Logs(mdb.SELECT, ctx.CONTEXT, s.Name) f.target = s }) } @@ -144,7 +123,6 @@ func (f *Frame) scan(m *ice.Message, h, line string) *Frame { } f.count++ - mdb.ZoneInsert(m.Spawn(), mdb.HASH, h, mdb.TEXT, bio.Text()) if strings.HasSuffix(bio.Text(), "\\") { line += bio.Text()[:len(bio.Text())-1] @@ -189,9 +167,6 @@ func (f *Frame) Start(m *ice.Message, arg ...string) bool { f.pipe, f.stdin, f.stdout = w, r, os.Stdout m.Option(ice.MSG_OPTS, ice.MSG_USERNAME) - m.Conf(SOURCE, kit.Keys(mdb.HASH, STDIO, kit.Keym(mdb.NAME)), STDIO) - m.Conf(SOURCE, kit.Keys(mdb.HASH, STDIO, kit.Keym(mdb.TIME)), m.Time()) - f.count = kit.Int(m.Conf(SOURCE, kit.Keys(mdb.HASH, STDIO, kit.Keym(mdb.COUNT)))) + 1 f.scan(m, STDIO, "") default: // 脚本文件 @@ -206,7 +181,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.Result(0) == ice.ErrWarn { + if msg := m.Cmd(nfs.CAT, f.source); msg.IsErr() { return true // 查找失败 } else { buf := bytes.NewBuffer(make([]byte, 0, ice.MOD_BUFS)) @@ -214,8 +189,7 @@ func (f *Frame) Start(m *ice.Message, arg ...string) bool { defer func() { m.Echo(buf.String()) }() } - f.count = 1 - f.scan(m, mdb.HashCreate(m.Spawn(), mdb.NAME, f.source).Result(), "") + f.scan(m, "", "") } return true } @@ -251,12 +225,7 @@ func init() { PS2, []ice.Any{mdb.COUNT, " ", TARGET, "> "}, )}, }, Commands: ice.Commands{ - SOURCE: {Name: "source file", Help: "脚本解析", Actions: ice.MergeAction(ice.Actions{ - gdb.RESTART: {Name: "restart", Help: "执行", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(SCREEN, m.Option(mdb.TEXT)) - m.ProcessInner() - }}, - }, mdb.ZoneAction()), Hand: func(m *ice.Message, arg ...string) { + SOURCE: {Name: "source file", Help: "脚本解析", Hand: func(m *ice.Message, arg ...string) { if f, ok := m.Target().Server().(*Frame); ok { f.Spawn(m, m.Target()).Start(m, arg...) } diff --git a/base/ssh/ssh.shy b/base/ssh/ssh.shy index 65c2d4a7..8484c085 100644 --- a/base/ssh/ssh.shy +++ b/base/ssh/ssh.shy @@ -1,8 +1,8 @@ chapter "ssh" -field "脚本" ssh.source -field "模块" ssh.target -field "提示" ssh.prompt -field "输出" ssh.printf -field "屏显" ssh.screen +field "脚本" source +field "模块" target +field "提示" prompt +field "输出" printf +field "屏显" screen diff --git a/base/tcp/client.go b/base/tcp/client.go index 8d65700d..228c3264 100644 --- a/base/tcp/client.go +++ b/base/tcp/client.go @@ -5,7 +5,6 @@ import ( ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/mdb" - kit "shylinux.com/x/toolkits" ) type Stat struct { @@ -41,23 +40,11 @@ func _client_dial(m *ice.Message, arg ...string) { defer c.Close() } - switch cb := m.OptionCB(CLIENT).(type) { - case func(net.Conn, error): - cb(c, e) + switch cb := m.OptionCB("").(type) { case func(net.Conn): if !m.Warn(e) { cb(c) } - case func(net.Conn, []byte, error): - b := make([]byte, ice.MOD_BUFS) - for { - n, e := c.Read(b) - if cb(c, b[:n], e); e != nil { - break - } - } - case nil: - c.Write([]byte("hello world\n")) default: m.ErrorNotImplement(cb) } @@ -80,16 +67,11 @@ const CLIENT = "client" func init() { Index.MergeCommands(ice.Commands{ CLIENT: {Name: "client hash auto prunes", Help: "客户端", Actions: ice.MergeAction(ice.Actions{ - ice.CTX_EXIT: {Hand: func(m *ice.Message, arg ...string) { - m.Conf(m.PrefixKey(), "", "") - }}, + ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { m.Conf("", mdb.HASH, "") }}, + ice.CTX_EXIT: {Hand: func(m *ice.Message, arg ...string) {}}, DIAL: {Name: "dial type name port=9010 host=", Help: "连接", Hand: func(m *ice.Message, arg ...string) { _client_dial(m, arg...) }}, - }, mdb.HashActionStatus(mdb.FIELD, "time,hash,status,type,name,host,port,error,nread,nwrite")), Hand: func(m *ice.Message, arg ...string) { - mdb.HashSelect(m, arg...).Tables(func(value ice.Maps) { - m.PushButton(kit.Select("", mdb.REMOVE, value[STATUS] == OPEN)) - }) - }}, + }, mdb.HashStatusAction(mdb.FIELD, "time,hash,status,type,name,host,port,error,nread,nwrite"))}, }) } diff --git a/base/tcp/host.go b/base/tcp/host.go index cd6ac8a0..6ca828c1 100644 --- a/base/tcp/host.go +++ b/base/tcp/host.go @@ -50,11 +50,11 @@ func _islocalhost(m *ice.Message, ip string) (ok bool) { if ip == "::1" || strings.HasPrefix(ip, "127.") { return true } - if m.Richs(HOST, kit.Keym(aaa.BLACK), ip, nil) != nil { + if mdb.Richs(m, HOST, kit.Keym(aaa.BLACK), ip, nil) != nil { return false } - if m.Richs(HOST, kit.Keym(aaa.WHITE), ip, nil) != nil { - m.Log_AUTH(aaa.WHITE, ip) + if mdb.Richs(m, HOST, kit.Keym(aaa.WHITE), ip, nil) != nil { + m.Logs(ice.LOG_AUTH, aaa.WHITE, ip) return true } return false @@ -72,12 +72,12 @@ func init() { m.Cmd(HOST).Tables(func(value ice.Maps) { m.Cmd(HOST, aaa.WHITE, value[aaa.IP]) }) }}, aaa.BLACK: {Name: "black", Help: "黑名单", Hand: func(m *ice.Message, arg ...string) { - m.Log_CREATE(aaa.BLACK, arg[0]) - m.Rich(HOST, kit.Keym(aaa.BLACK), kit.Dict(mdb.TEXT, arg[0])) + m.Logs(mdb.CREATE, aaa.BLACK, arg[0]) + mdb.Rich(m, HOST, kit.Keym(aaa.BLACK), kit.Dict(mdb.TEXT, arg[0])) }}, aaa.WHITE: {Name: "white", Help: "白名单", Hand: func(m *ice.Message, arg ...string) { - m.Log_CREATE(aaa.WHITE, arg[0]) - m.Rich(HOST, kit.Keym(aaa.WHITE), kit.Dict(mdb.TEXT, arg[0])) + m.Logs(mdb.CREATE, aaa.WHITE, arg[0]) + mdb.Rich(m, HOST, kit.Keym(aaa.WHITE), kit.Dict(mdb.TEXT, arg[0])) }}, }, mdb.HashAction(aaa.BLACK, kit.Data(mdb.SHORT, mdb.TEXT), aaa.WHITE, kit.Data(mdb.SHORT, mdb.TEXT))), Hand: func(m *ice.Message, arg ...string) { _host_list(m, kit.Select("", arg, 0)) diff --git a/base/tcp/port.go b/base/tcp/port.go index e52cbf88..32a5dc8f 100644 --- a/base/tcp/port.go +++ b/base/tcp/port.go @@ -30,7 +30,7 @@ func _port_right(m *ice.Message, arg ...string) string { } nfs.MkdirAll(m, p) - m.Log_SELECT(PORT, i) + m.Logs(mdb.SELECT, PORT, i) return m.Config(CURRENT, i) } return "" diff --git a/base/tcp/server.go b/base/tcp/server.go index 1030b122..41eabca1 100644 --- a/base/tcp/server.go +++ b/base/tcp/server.go @@ -28,15 +28,12 @@ func (l Listener) Close() error { func _server_listen(m *ice.Message, arg ...string) { l, e := net.Listen(TCP, m.Option(HOST)+":"+m.Option(PORT)) - l = &Listener{m: m, h: m.Cmdx(mdb.INSERT, SERVER, "", mdb.HASH, - arg, STATUS, kit.Select(ERROR, OPEN, e == nil), ERROR, kit.Format(e), kit.Dict(mdb.TARGET, l)), s: &Stat{}, Listener: l} + 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)).Result(), s: &Stat{}, Listener: l} if e == nil { defer l.Close() } - switch cb := m.OptionCB(SERVER).(type) { - case func(net.Listener, error): - cb(l, e) + switch cb := m.OptionCB("").(type) { case func(net.Listener): m.Assert(e) cb(l) @@ -48,27 +45,8 @@ func _server_listen(m *ice.Message, arg ...string) { break } } - case func(net.Conn, error): - for { - c, e := l.Accept() - if cb(c, e); e != nil { - break - } - } default: - for { - c, e := l.Accept() - if e != nil { - break - } - - b := make([]byte, ice.MOD_BUFS) - if n, e := c.Read(b); e == nil { - m.Info("nonce", string(b[:n])) - c.Write(b[:n]) - } - c.Close() - } + m.ErrorNotImplement(cb) } } @@ -85,26 +63,11 @@ const SERVER = "server" func init() { Index.MergeCommands(ice.Commands{ SERVER: {Name: "server hash auto prunes", Help: "服务器", Actions: ice.MergeAction(ice.Actions{ - ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { - m.Conf("", mdb.HASH, "") - }}, - ice.CTX_EXIT: {Hand: func(m *ice.Message, arg ...string) { - mdb.HashSelectValue(m, func(target ice.Any) { - if l, ok := target.(net.Listener); ok { - l.Close() - } - if l, ok := target.(*Listener); ok { - l.Close() - } - }) - }}, - LISTEN: {Name: "LISTEN type name port=9030 host=", Help: "监听", Hand: func(m *ice.Message, arg ...string) { + ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { m.Conf("", mdb.HASH, "") }}, + ice.CTX_EXIT: {Hand: func(m *ice.Message, arg ...string) { mdb.HashSelectClose(m) }}, + LISTEN: {Name: "listen type name port=9030 host=", Help: "监听", Hand: func(m *ice.Message, arg ...string) { _server_listen(m, arg...) }}, - }, mdb.HashActionStatus(mdb.FIELD, "time,hash,status,type,name,host,port,error,nconn")), Hand: func(m *ice.Message, arg ...string) { - mdb.HashSelect(m, arg...).Tables(func(value ice.Maps) { - m.PushButton(kit.Select("", mdb.REMOVE, value[STATUS] == CLOSE)) - }) - }}, + }, mdb.HashStatusCloseAction(mdb.FIELD, "time,hash,status,type,name,host,port,error,nconn"))}, }) } diff --git a/base/tcp/tcp.shy b/base/tcp/tcp.shy index e6a4fd00..9a0e307b 100644 --- a/base/tcp/tcp.shy +++ b/base/tcp/tcp.shy @@ -1,6 +1,6 @@ chapter "tcp" -field "主机" tcp.host -field "端口" tcp.port -field "客户端" tcp.client -field "服务器" tcp.server +field "主机" host +field "端口" port +field "客户端" client +field "服务器" server diff --git a/base/web/broad.go b/base/web/broad.go index 21fa678d..5536206d 100644 --- a/base/web/broad.go +++ b/base/web/broad.go @@ -20,7 +20,7 @@ func _broad_send(m *ice.Message, host, port string, remote_host, remote_port str if s, e := net.DialUDP("udp", nil, _broad_addr(m, remote_host, remote_port)); m.Assert(e) { defer s.Close() msg := m.Spawn(kit.Dict(tcp.HOST, host, tcp.PORT, port)) - m.Log_EXPORT(BROAD, msg.FormatMeta(), "to", remote_host+ice.DF+remote_port) + m.Logs(mdb.EXPORT, BROAD, msg.FormatMeta(), "to", remote_host+ice.DF+remote_port) s.Write([]byte(msg.FormatMeta())) } } @@ -28,7 +28,7 @@ func _broad_serve(m *ice.Message, host, port string) { _broad_send(m, host, port, "255.255.255.255", "9020") if s, e := net.ListenUDP("udp", _broad_addr(m, "0.0.0.0", port)); m.Assert(e) { defer s.Close() - m.Cmd(BROAD, mdb.CREATE, tcp.HOST, host, tcp.PORT, port, kit.Dict(mdb.TARGET, s)) + mdb.HashCreate(m, tcp.HOST, host, tcp.PORT, port, kit.Dict(mdb.TARGET, s)) buf := make([]byte, ice.MOD_BUFS) for { @@ -36,7 +36,7 @@ func _broad_serve(m *ice.Message, host, port string) { if err != nil { break } - m.Log_IMPORT(BROAD, string(buf[:n]), "from", addr) + m.Logs(mdb.IMPORT, BROAD, string(buf[:n]), "from", addr) msg := m.Spawn(buf[:n]) if m.Cmd(BROAD, kit.Format("%s,%s", msg.Option(tcp.HOST), msg.Option(tcp.PORT))).Length() > 0 { @@ -44,11 +44,11 @@ func _broad_serve(m *ice.Message, host, port string) { } if remote, err := net.ResolveUDPAddr("udp4", kit.Format("%s:%s", msg.Option(tcp.HOST), msg.Option(tcp.PORT))); !m.Warn(err) { - m.Cmd(BROAD).Tables(func(value ice.Maps) { - m.Log_EXPORT(BROAD, kit.Format(value), "to", kit.Format(remote)) + m.Cmd(BROAD, func(value ice.Maps) { + m.Logs(mdb.EXPORT, BROAD, kit.Format(value), "to", kit.Format(remote)) s.WriteToUDP([]byte(m.Spawn(value).FormatMeta()), remote) }) - m.Cmd(BROAD, mdb.CREATE, msg.OptionSimple(tcp.HOST, tcp.PORT)) + mdb.HashCreate(m, msg.OptionSimple(tcp.HOST, tcp.PORT)) } } } @@ -67,13 +67,6 @@ const BROAD = "broad" func init() { Index.MergeCommands(ice.Commands{ BROAD: {Name: "broad hash auto serve", Help: "广播", Actions: ice.MergeAction(ice.Actions{ - ice.CTX_EXIT: {Hand: func(m *ice.Message, arg ...string) { - mdb.HashSelectValue(m, func(target ice.Any) { - if c, ok := target.(*net.UDPConn); ok { - c.Close() - } - }) - }}, mdb.SEARCH: {Name: "search type name text", Help: "搜索", Hand: func(m *ice.Message, arg ...string) { _broad_search(m, arg[0], arg[1], kit.Select("", arg, 2)) }}, @@ -85,6 +78,6 @@ func init() { kit.Format("http://%s:%s", m.Option(tcp.HOST), m.Option(tcp.PORT))) m.Cmd(SPACE, tcp.DIAL, m.OptionSimple(ice.DEV)) }}, - }, mdb.HashAction(mdb.SHORT, "host,port", mdb.FIELD, "time,hash,host,port", mdb.ACTION, "space"))}, + }, mdb.HashCloseAction(mdb.SHORT, "host,port", mdb.FIELD, "time,hash,host,port", mdb.ACTION, SPACE))}, }) } diff --git a/base/web/cache.go b/base/web/cache.go index 2bc4bfc4..7abceef2 100644 --- a/base/web/cache.go +++ b/base/web/cache.go @@ -71,7 +71,7 @@ func _cache_upload(m *ice.Message, r *http.Request) (kind, name, file, size stri // 导入数据 b.Seek(0, os.SEEK_SET) if n, e := io.Copy(f, b); m.Assert(e) { - m.Log_IMPORT(nfs.FILE, p, nfs.SIZE, kit.FmtSize(int64(n))) + m.Logs(mdb.IMPORT, nfs.FILE, p, nfs.SIZE, kit.FmtSize(int64(n))) return h.Header.Get(ContentType), h.Filename, p, kit.Format(n) } } @@ -100,7 +100,7 @@ func _cache_download(m *ice.Message, r *http.Response) (file, size string) { cb(size, total) default: if s != step && s%10 == 0 { - m.Log_IMPORT(nfs.FILE, p, mdb.VALUE, s, mdb.COUNT, kit.FmtSize(int64(size)), mdb.TOTAL, kit.FmtSize(int64(total))) + m.Logs(mdb.IMPORT, nfs.FILE, p, mdb.VALUE, s, mdb.COUNT, kit.FmtSize(int64(size)), mdb.TOTAL, kit.FmtSize(int64(total))) } } @@ -119,6 +119,8 @@ const ( WRITE = "write" UPLOAD = "upload" DOWNLOAD = "download" + + UPLOAD_WATCH = "upload_watch" ) const CACHE = "cache" @@ -146,6 +148,19 @@ func init() { _cache_save(m, arg[0], arg[1], "", file, size) } }}, + UPLOAD_WATCH: {Name: "upload_watch", Help: "上传", Hand: func(m *ice.Message, arg ...string) { + up := kit.Simple(m.Optionv(ice.MSG_UPLOAD)) + if len(up) < 2 { + msg := m.Cmd(CACHE, UPLOAD) + up = kit.Simple(msg.Append(mdb.HASH), msg.Append(mdb.NAME), msg.Append(nfs.SIZE)) + } + + if p := path.Join(arg[0], up[1]); m.Option(ice.MSG_USERPOD) == "" { + m.Cmdy(CACHE, WATCH, up[0], p) // 本机文件 + } else { // 下发文件 + m.Cmdy(SPIDE, ice.DEV, ice.SAVE, p, SPIDE_GET, MergeURL2(m, path.Join(SHARE_CACHE, up[0]))) + } + }}, }, mdb.HashAction(mdb.SHORT, mdb.TEXT, mdb.FIELD, "time,hash,size,type,name,text,file")), Hand: func(m *ice.Message, arg ...string) { if mdb.HashSelect(m, arg...); len(arg) == 0 { return @@ -153,7 +168,7 @@ func init() { if m.Append(nfs.FILE) == "" { m.PushScript("inner", m.Append(mdb.TEXT)) } else { - m.PushDownload(m.Append(mdb.NAME), m.MergeURL2(SHARE_CACHE+arg[0])) + m.PushDownload(m.Append(mdb.NAME), MergeURL2(m, SHARE_CACHE+arg[0])) } }}, PP(CACHE): {Name: "/cache/", Help: "缓存池", Hand: func(m *ice.Message, arg ...string) { diff --git a/base/web/dream.go b/base/web/dream.go index fd816ab0..702874d7 100644 --- a/base/web/dream.go +++ b/base/web/dream.go @@ -7,21 +7,22 @@ import ( ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/cli" + "shylinux.com/x/icebergs/base/ctx" + "shylinux.com/x/icebergs/base/gdb" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" "shylinux.com/x/icebergs/base/tcp" kit "shylinux.com/x/toolkits" - "shylinux.com/x/toolkits/file" ) func _dream_list(m *ice.Message) *ice.Message { list := m.CmdMap(SPACE, mdb.NAME) - m.Cmdy(nfs.DIR, ice.USR_LOCAL_WORK, "time,size,name").Tables(func(value ice.Maps) { + m.Cmdy(nfs.DIR, ice.USR_LOCAL_WORK, "time,size,name", func(value ice.Maps) { if dream, ok := list[value[mdb.NAME]]; ok { m.Push(mdb.TYPE, dream[mdb.TYPE]) m.Push(cli.STATUS, cli.START) m.PushButton("vimer", "xterm", cli.OPEN, cli.STOP) - m.PushAnchor(strings.Split(m.MergePod(value[mdb.NAME]), "?")[0]) + m.PushAnchor(strings.Split(MergePod(m, value[mdb.NAME]), "?")[0]) text := []string{} for _, line := range kit.Split(m.Cmdx(SPACE, value[mdb.NAME], cli.SYSTEM, "git", "diff", "--shortstat"), ice.FS, ice.FS) { if list := kit.Split(line); strings.Contains(line, "file") { @@ -41,16 +42,18 @@ func _dream_list(m *ice.Message) *ice.Message { m.Push(mdb.TEXT, "") } }) - return m.Sort("status,type,name").StatusTimeCount(cli.START, len(list)) + m.Sort("status,type,name") + m.StatusTimeCount(cli.START, len(list)) + return m } func _dream_show(m *ice.Message, name string) { if !strings.Contains(name, "-") || !strings.HasPrefix(name, "20") { name = m.Time("20060102-") + kit.ReplaceAll(name, "-", "_") } - defer m.ProcessOpen(m.MergePod(m.Option(mdb.NAME, name))) - defer m.Echo(m.MergePod(m.Option(mdb.NAME, name))) - defer m.PushRefresh() + defer m.ProcessOpen(MergePod(m, m.Option(mdb.NAME, name))) + defer m.Echo(MergePod(m, m.Option(mdb.NAME, name))) + // defer m.PushRefresh() p := path.Join(ice.USR_LOCAL_WORK, name) if pid := m.Cmdx(nfs.CAT, path.Join(p, ice.Info.PidPath)); pid != "" && kit.FileExists("/proc/"+pid) { @@ -63,7 +66,7 @@ func _dream_show(m *ice.Message, name string) { if m.Option(nfs.REPOS) != "" { // 下载源码 m.Cmd("web.code.git.repos", mdb.CREATE, m.OptionSimple(nfs.REPOS), nfs.PATH, p) } else { // 创建目录 - file.MkdirAll(p, ice.MOD_DIR) + nfs.MkdirAll(m, p) } // 目录文件 @@ -72,7 +75,7 @@ func _dream_show(m *ice.Message, name string) { ice.ETC_MISS_SH, ice.SRC_MAIN_SHY, ice.SRC_MAIN_GO, ice.GO_MOD, ice.MAKEFILE, ice.README_MD, } { - if kit.FileExists(path.Join(p, file)) { + if nfs.ExistsFile(m, path.Join(p, file)) { continue } switch m.Cmdy(nfs.COPY, path.Join(p, file), path.Join(ice.USR_LOCAL_WORK, m.Option(nfs.TEMPLATE), file)); file { @@ -83,7 +86,7 @@ func _dream_show(m *ice.Message, name string) { } } } - m.Cmd(nfs.DEFS, path.Join(p, ice.ETC_MISS_SH), m.Config("miss")) + m.Cmd(nfs.DEFS, path.Join(p, ice.ETC_MISS_SH), m.Config(nfs.SCRIPT)) // 环境变量 m.Optionv(cli.CMD_DIR, kit.Path(p)) @@ -95,14 +98,14 @@ func _dream_show(m *ice.Message, name string) { )) m.Optionv(cli.CMD_OUTPUT, path.Join(p, ice.BIN_BOOT_LOG)) - defer m.ToastProcess()() + defer ToastProcess(m)() bin := kit.Select(os.Args[0], cli.SystemFind(m, ice.ICE_BIN, kit.Path(path.Join(p, ice.BIN)), kit.Path(ice.BIN))) m.Cmd(cli.DAEMON, bin, SPACE, tcp.DIAL, ice.DEV, ice.OPS, m.OptionSimple(mdb.NAME, RIVER)) - m.Sleep3s() - m.Option(cli.CMD_ENV, "") + defer gdb.Event(m, DREAM_CREATE, m.OptionSimple(mdb.TYPE, mdb.NAME)...) m.Option(cli.CMD_OUTPUT, "") - m.Event(DREAM_CREATE, m.OptionSimple(mdb.TYPE, mdb.NAME)...) + m.Option(cli.CMD_ENV, "") + m.Sleep3s() } const ( @@ -115,12 +118,10 @@ const DREAM = "dream" func init() { Index.MergeCommands(ice.Commands{ DREAM: {Name: "dream name path auto start", Help: "梦想家", Actions: ice.MergeAction(ice.Actions{ - ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { - m.Config("miss", _dream_miss) - }}, + ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { m.Config(nfs.SCRIPT, _dream_script) }}, mdb.INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) { switch arg[0] { - case "repos": + case nfs.REPOS: default: _dream_list(m).Cut("name,status,time") } @@ -129,13 +130,13 @@ func init() { _dream_show(m, m.Option(mdb.NAME, kit.Select(path.Base(m.Option(nfs.REPOS)), m.Option(mdb.NAME)))) }}, cli.OPEN: {Name: "open", Help: "打开", Hand: func(m *ice.Message, arg ...string) { - m.ProcessOpen(m.MergePod(m.Option(mdb.NAME), "", "")) + m.ProcessOpen(MergePod(m, m.Option(mdb.NAME), "", "")) }}, "vimer": {Name: "vimer", Help: "编辑", Hand: func(m *ice.Message, arg ...string) { - m.ProcessOpen(m.MergePod(m.Option(mdb.NAME)+"/cmd/web.code.vimer", "", "")) + m.ProcessOpen(MergePod(m, m.Option(mdb.NAME)+"/cmd/web.code.vimer", "", "")) }}, "xterm": {Name: "xterm", Help: "命令", Hand: func(m *ice.Message, arg ...string) { - m.ProcessOpen(m.MergePod(m.Option(mdb.NAME)+"/cmd/web.code.xterm", "", "")) + m.ProcessOpen(MergePod(m, m.Option(mdb.NAME)+"/cmd/web.code.xterm", "", "")) }}, cli.STOP: {Name: "stop", Help: "停止", Hand: func(m *ice.Message, arg ...string) { m.Cmd(SPACE, mdb.MODIFY, m.OptionSimple(mdb.NAME), mdb.STATUS, cli.STOP) @@ -147,26 +148,26 @@ func init() { m.Cmd(mdb.DELETE, m.Prefix(SPACE), "", mdb.HASH, m.OptionSimple(mdb.NAME)) } else { m.Cmd(mdb.DELETE, m.Prefix(SPACE), "", mdb.HASH, m.OptionSimple(mdb.NAME)) - m.Sleep("3s", DREAM, cli.START, m.OptionSimple(mdb.NAME)) + m.Sleep3s(DREAM, cli.START, m.OptionSimple(mdb.NAME)) } }}, nfs.TRASH: {Name: "trash", Help: "删除", Hand: func(m *ice.Message, arg ...string) { m.Cmd(nfs.TRASH, mdb.CREATE, path.Join(ice.USR_LOCAL_WORK, m.Option(mdb.NAME))) m.ProcessRefresh30ms() }}, - }, mdb.HashAction("miss", _dream_miss)), Hand: func(m *ice.Message, arg ...string) { + }, mdb.HashAction(nfs.SCRIPT, _dream_script)), Hand: func(m *ice.Message, arg ...string) { if len(arg) == 0 { if _dream_list(m); !m.IsMobileUA() { - m.Display("/plugin/table.js?style=card") + ctx.DisplayTableCard(m) } - return + } else { + m.Cmdy(nfs.CAT, arg[1:], kit.Dict(nfs.DIR_ROOT, path.Join(ice.USR_LOCAL_WORK, arg[0]))) } - m.Cmdy(nfs.CAT, arg[1:], kit.Dict(nfs.DIR_ROOT, path.Join(ice.USR_LOCAL_WORK, arg[0]))) }}, }) } -var _dream_miss = `#! /bin/sh +var _dream_script = `#! /bin/sh require &>/dev/null || if [ -f $PWD/.ish/plug.sh ]; then source $PWD/.ish/plug.sh; elif [ -f $HOME/.ish/plug.sh ]; then source $HOME/.ish/plug.sh; else ctx_temp=$(mktemp); if curl -h &>/dev/null; then curl -o $ctx_temp -fsSL https://shylinux.com; else wget -O $ctx_temp -q http://shylinux.com; fi; source $ctx_temp intshell diff --git a/base/web/option.go b/base/web/option.go new file mode 100644 index 00000000..5977cd18 --- /dev/null +++ b/base/web/option.go @@ -0,0 +1,132 @@ +package web + +import ( + "net/url" + "path" + "strings" + "time" + + ice "shylinux.com/x/icebergs" + "shylinux.com/x/icebergs/base/cli" + "shylinux.com/x/icebergs/base/gdb" + "shylinux.com/x/icebergs/base/mdb" + kit "shylinux.com/x/toolkits" + "shylinux.com/x/toolkits/file" +) + +func PushNotice(m *ice.Message, arg ...ice.Any) { + m.Optionv(ice.MSG_OPTS, m.Optionv(ice.MSG_OPTION)) + if m.Option(ice.MSG_USERPOD) == "" { + m.Cmd(SPACE, m.Option(ice.MSG_DAEMON), arg) + } else { + opts := kit.Dict(ice.POD, m.Option(ice.MSG_DAEMON), "cmds", kit.Simple(arg...)) + for _, k := range kit.Simple(m.Optionv(ice.MSG_OPTS)) { + opts[k] = m.Option(k) + } + m.Cmd("web.spide", ice.OPS, MergeURL2(m, SHARE_TOAST), kit.Format(opts)) + } +} +func PushNoticeGrow(m *ice.Message, arg ...ice.Any) { + PushNotice(m, kit.List("grow", arg)...) +} +func PushNoticeToast(m *ice.Message, arg ...ice.Any) { + PushNotice(m, kit.List("toast", arg)...) +} +func PushNoticeRefresh(m *ice.Message, arg ...ice.Any) { + PushNotice(m, kit.List("refresh")...) +} + +func ToastProcess(m *ice.Message, arg ...ice.Any) func() { + if len(arg) == 0 { + arg = kit.List("", "-1") + } + if len(arg) == 1 { + arg = append(arg, "-1") + } + Toast(m, ice.PROCESS, arg...) + return func() { Toast(m, ice.SUCCESS) } +} +func ToastRestart(m *ice.Message, arg ...ice.Any) { Toast(m, gdb.RESTART, arg...) } +func ToastFailure(m *ice.Message, arg ...ice.Any) { Toast(m, ice.FAILURE, arg...) } +func ToastSuccess(m *ice.Message, arg ...ice.Any) { Toast(m, ice.SUCCESS, arg...) } +func Toast(m *ice.Message, text string, arg ...ice.Any) { // [title [duration [progress]]] + if len(arg) > 1 { + switch val := arg[1].(type) { + case string: + if value, err := time.ParseDuration(val); err == nil { + arg[1] = int(value / time.Millisecond) + } + } + } + + PushNoticeToast(m, "", text, arg) +} +func Toast3s(m *ice.Message, text string, arg ...ice.Any) { + Toast(m, text, kit.List(kit.Select("", arg, 0), kit.Select("3s", arg, 1))...) +} +func Toast30s(m *ice.Message, text string, arg ...ice.Any) { + Toast(m, text, kit.List(kit.Select("", arg, 0), kit.Select("30s", arg, 1))...) +} +func GoToast(m *ice.Message, title string, cb func(toast func(string, int, int))) { + m.Go(func() { + cb(func(name string, count, total int) { + Toast(m, + kit.Format("%s %s/%s", name, strings.TrimSuffix(kit.FmtSize(int64(count)), "B"), strings.TrimSuffix(kit.FmtSize(int64(total)), "B")), + kit.Format("%s %d%%", title, count*100/total), + kit.Select("3000", "30000", count < total), + count*100/total, + ) + }) + }) +} +func PushStream(m *ice.Message) { + m.Option(cli.CMD_OUTPUT, file.NewWriteCloser(func(buf []byte) (int, error) { + PushNoticeGrow(m, string(buf)) + return len(buf), nil + }, func() error { PushNoticeToast(m, "done"); return nil })) +} +func PushPodCmd(m *ice.Message, cmd string, arg ...string) { + if m.Length() > 0 && len(m.Appendv(ice.POD)) == 0 { + m.Tables(func(value ice.Maps) { m.Push(ice.POD, m.Option(ice.MSG_USERPOD)) }) + } + + m.Cmd(SPACE, ice.OptionFields(mdb.TYPE, mdb.NAME)).Tables(func(value ice.Maps) { + switch value[mdb.TYPE] { + case SERVER, WORKER: + if value[mdb.NAME] == ice.Info.HostName { + break + } + m.Cmd(SPACE, value[mdb.NAME], m.Prefix(cmd), arg).Table(func(index int, val ice.Maps, head []string) { + val[ice.POD] = kit.Keys(value[mdb.NAME], val[ice.POD]) + m.Push("", val, head) + }) + } + }) +} + +func OptionUserWeb(m *ice.Message) *url.URL { + return kit.ParseURL(m.Option(ice.MSG_USERWEB)) +} +func MergeURL2(m *ice.Message, url string, arg ...ice.Any) string { + return kit.MergeURL2(m.Option(ice.MSG_USERWEB), url, arg...) +} +func MergeLink(m *ice.Message, url string, arg ...ice.Any) string { + return strings.Split(MergeURL2(m, url, arg...), "?")[0] +} +func MergePod(m *ice.Message, pod string, arg ...ice.Any) string { + return kit.MergePOD(kit.Select(ice.Info.Domain, m.Option(ice.MSG_USERWEB)), pod, arg...) +} +func MergeCmd(m *ice.Message, cmd string, arg ...ice.Any) string { + return mergeurl(m, path.Join(ice.CMD, kit.Select(m.PrefixKey(), cmd)), arg...) +} +func MergeWebsite(m *ice.Message, web string, arg ...ice.Any) string { + return mergeurl(m, path.Join(WEBSITE, web), arg...) +} +func mergeurl(m *ice.Message, p string, arg ...ice.Any) string { + if m.Option(ice.MSG_USERPOD) == "" { + p = path.Join("/", p) + } else { + p = path.Join("/chat", ice.POD, m.Option(ice.MSG_USERPOD), p) + } + return kit.MergeURL2(kit.Select(ice.Info.Domain, m.Option(ice.MSG_USERWEB)), path.Join(p), arg...) +} diff --git a/base/web/render.go b/base/web/render.go index 8088e529..c2ef1e88 100644 --- a/base/web/render.go +++ b/base/web/render.go @@ -10,6 +10,8 @@ import ( ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/aaa" + "shylinux.com/x/icebergs/base/ctx" + "shylinux.com/x/icebergs/base/lex" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" "shylinux.com/x/icebergs/base/tcp" @@ -23,7 +25,7 @@ const ( func Render(msg *ice.Message, cmd string, args ...ice.Any) { if cmd != "" { - defer func() { msg.Log_EXPORT(cmd, args) }() + defer func() { msg.Logs(mdb.EXPORT, cmd, args) }() } switch arg := kit.Simple(args...); cmd { @@ -31,18 +33,18 @@ func Render(msg *ice.Message, cmd string, args ...ice.Any) { RenderCookie(msg, arg[0], arg[1:]...) case STATUS, ice.RENDER_STATUS: // [code [text]] - RenderStatus(msg, kit.Int(kit.Select("200", arg, 0)), kit.Select("", arg, 1)) + RenderStatus(msg.W, kit.Int(kit.Select("200", arg, 0)), kit.Select("", arg, 1)) case ice.RENDER_REDIRECT: // url [arg...] - RenderRedirect(msg, arg...) + http.Redirect(msg.W, msg.R, kit.MergeURL(arg[0], arg[1:]), http.StatusTemporaryRedirect) case ice.RENDER_DOWNLOAD: // file [type [name]] if strings.HasPrefix(arg[0], ice.HTTP) { - http.Redirect(msg.W, msg.R, arg[0], http.StatusSeeOther) + RenderRedirect(msg, arg[0]) break } - msg.W.Header().Set("Content-Disposition", fmt.Sprintf("filename=%s", kit.Select(path.Base(kit.Select(arg[0], msg.Option("filename"))), arg, 2))) RenderType(msg.W, arg[0], kit.Select("", arg, 1)) + RenderHeader(msg.W, "Content-Disposition", fmt.Sprintf("filename=%s", kit.Select(path.Base(kit.Select(arg[0], msg.Option("filename"))), arg, 2))) if _, e := nfs.DiskFile.StatFile(arg[0]); e == nil { http.ServeFile(msg.W, msg.R, kit.Path(arg[0])) } else if f, e := nfs.PackFile.OpenFile(arg[0]); e == nil { @@ -59,19 +61,16 @@ func Render(msg *ice.Message, cmd string, args ...ice.Any) { } case ice.RENDER_JSON: - msg.W.Header().Set("Content-Type", "application/json") + RenderType(msg.W, nfs.JSON, "") msg.W.Write([]byte(arg[0])) case ice.RENDER_VOID: // no output - case ice.RENDER_RAW: - fallthrough default: for _, k := range []string{ - "_", "_option", "_handle", "_output", "", - "cmds", "fields", "sessid", "domain", - "river", "storm", + "_option", "_handle", "_output", + "cmds", "fields", "sessid", "river", "storm", } { msg.Set(k) } @@ -79,37 +78,37 @@ func Render(msg *ice.Message, cmd string, args ...ice.Any) { if cmd != "" && cmd != ice.RENDER_RAW { // [str [arg...]] msg.Echo(kit.Format(cmd, args...)) } - msg.W.Header().Set(ContentType, ContentJSON) + RenderType(msg.W, nfs.JSON, "") fmt.Fprint(msg.W, msg.FormatMeta()) } } -func RenderType(w http.ResponseWriter, name, mime string) { - if mime != "" { - w.Header().Set(ContentType, mime) - return - } - switch kit.Ext(name) { - case nfs.CSS: - w.Header().Set(ContentType, "text/css; charset=utf-8") - case "pdf": - w.Header().Set(ContentType, "application/pdf") +func RenderType(w http.ResponseWriter, name, mime string) { + if mime == "" { + switch kit.Ext(name) { + case nfs.HTML: + mime = "text/html" + case nfs.CSS: + mime = "text/css; charset=utf-8" + default: + mime = "application/" + kit.Ext(name) + } } + RenderHeader(w, ContentType, mime) } -func RenderHeader(msg *ice.Message, key, value string) { - msg.W.Header().Set(key, value) +func RenderHeader(w http.ResponseWriter, key, value string) { + w.Header().Set(key, value) } func RenderCookie(msg *ice.Message, value string, arg ...string) { // name path expire expire := time.Now().Add(kit.Duration(kit.Select(msg.Conf(aaa.SESS, kit.Keym(mdb.EXPIRE)), arg, 2))) http.SetCookie(msg.W, &http.Cookie{Value: value, Name: kit.Select(CookieName(msg.Option(ice.MSG_USERWEB)), arg, 0), Path: kit.Select(ice.PS, arg, 1), Expires: expire}) } -func RenderStatus(msg *ice.Message, code int, text string) { - msg.W.WriteHeader(code) - msg.W.Write([]byte(text)) +func RenderStatus(w http.ResponseWriter, code int, text string) { + w.WriteHeader(code) + w.Write([]byte(text)) } func RenderRefresh(msg *ice.Message, arg ...string) { // url text delay - msg.Render(ice.RENDER_VOID) Render(msg, ice.RENDER_RESULT, kit.Format(` @@ -120,19 +119,58 @@ func RenderRefresh(msg *ice.Message, arg ...string) { // url text delay `, kit.Select("3", arg, 2), kit.Select(msg.Option(ice.MSG_USERWEB), arg, 0), kit.Select("loading...", arg, 1))) + msg.Render(ice.RENDER_VOID) } -func RenderRedirect(msg *ice.Message, arg ...string) { - http.Redirect(msg.W, msg.R, kit.MergeURL(arg[0], arg[1:]), http.StatusTemporaryRedirect) +func RenderRedirect(msg *ice.Message, arg ...ice.Any) { + Render(msg, ice.RENDER_REDIRECT, arg...) + msg.Render(ice.RENDER_VOID) } func RenderDownload(msg *ice.Message, arg ...ice.Any) { Render(msg, ice.RENDER_DOWNLOAD, arg...) + msg.Render(ice.RENDER_VOID) } func RenderResult(msg *ice.Message, arg ...ice.Any) { Render(msg, ice.RENDER_RESULT, arg...) + msg.Render(ice.RENDER_VOID) } + func CookieName(url string) string { return ice.MSG_SESSID + "_" + kit.ReplaceAll(kit.ParseURLMap(url)[tcp.HOST], ".", "_", ":", "_") + return ice.MSG_SESSID + "_" + kit.ParseURLMap(url)[tcp.PORT] } -func Format(tag string, arg ...ice.Any) string { - return kit.Format("<%s>%s", tag, strings.Join(kit.Simple(arg), ""), tag) + +func RenderIndex(m *ice.Message, serve, repos string, file ...string) *ice.Message { + return m.RenderDownload(path.Join(m.Conf(serve, kit.Keym(repos, nfs.PATH)), kit.Select(m.Conf(serve, kit.Keym(repos, INDEX)), path.Join(file...)))) } +func RenderWebsite(m *ice.Message, pod string, dir string, arg ...string) *ice.Message { + args := []string{} + if pod != "" { + args = append(args, SPACE, pod) + } + m.Echo(m.Cmdx(args, "web.chat.website", lex.PARSE, dir, arg)) + return m.RenderResult() +} +func RenderCmd(m *ice.Message, index string, args ...ice.Any) { + list := index + if index != "" { + msg := m.Cmd(ctx.COMMAND, index) + list = kit.Format(kit.List(kit.Dict(msg.AppendSimple(mdb.NAME, mdb.HELP), + ctx.INDEX, index, ctx.ARGS, kit.Simple(args), ctx.DISPLAY, m.Option(ice.MSG_DISPLAY), + mdb.LIST, kit.UnMarshal(msg.Append(mdb.LIST)), mdb.META, kit.UnMarshal(msg.Append(mdb.META)), + ))) + } + m.Echo(kit.Format(_cans, list)) + m.RenderResult() +} + +var _cans = ` + + + + + + + + + +` diff --git a/base/web/route.go b/base/web/route.go index e4604790..9515bf85 100644 --- a/base/web/route.go +++ b/base/web/route.go @@ -23,7 +23,6 @@ func _route_travel(m *ice.Message, route string) { m.Push(mdb.TYPE, value[mdb.TYPE]) m.Push(ROUTE, kit.Keys(val[mdb.NAME], value[ROUTE])) }) - fallthrough case WORKER: // 本机查询 m.Push(mdb.TYPE, val[mdb.TYPE]) @@ -33,8 +32,7 @@ func _route_travel(m *ice.Message, route string) { } func _route_list(m *ice.Message) *ice.Message { m.Tables(func(value ice.Maps) { - m.PushAnchor(value[ROUTE], m.MergePod(value[ROUTE])) - switch value[mdb.TYPE] { + switch m.PushAnchor(value[ROUTE], MergePod(m, value[ROUTE])); value[mdb.TYPE] { case SERVER: m.PushButton(tcp.START, aaa.INVITE) case WORKER: @@ -45,7 +43,7 @@ func _route_list(m *ice.Message) *ice.Message { }) // 网卡信息 - u := kit.ParseURL(m.Option(ice.MSG_USERWEB)) + u := OptionUserWeb(m) m.Cmd(tcp.HOST).Tables(func(value ice.Maps) { m.Push(mdb.TYPE, MYSELF) m.Push(ROUTE, ice.Info.NodeName) @@ -80,8 +78,8 @@ func init() { }}, SPIDE: {Name: "spide", Help: "架构图", Hand: func(m *ice.Message, arg ...string) { if m.Option(ROUTE) == "" { // 路由列表 route + ctx.DisplayStorySpide(m, lex.PREFIX, SPIDE, lex.SPLIT, ice.PT) m.Cmdy(ROUTE).Cut(ROUTE) - m.DisplayStorySpide("prefix", "spide", lex.SPLIT, ice.PT) } else if m.Option(ctx.CONTEXT) == "" { // 模块列表 context m.Cmdy(SPACE, m.Option(ROUTE), ctx.CONTEXT, ice.ICE, ctx.CONTEXT).Cut(mdb.NAME).RenameAppend(mdb.NAME, ctx.CONTEXT) diff --git a/base/web/serve.go b/base/web/serve.go index 5647e20d..a360294a 100644 --- a/base/web/serve.go +++ b/base/web/serve.go @@ -5,7 +5,6 @@ import ( "io" "net/http" "net/url" - "os" "path" "strings" @@ -27,35 +26,35 @@ func AddRewrite(cb ice.Any) { rewriteList = append(rewriteList, cb) } func _serve_rewrite(m *ice.Message) { AddRewrite(func(w http.ResponseWriter, r *http.Request) bool { - msg, repos := m.Spawn(SERVE, w, r), kit.Select(ice.INTSHELL, ice.VOLCANOS, strings.Contains(r.Header.Get("User-Agent"), "Mozilla/5.0")) - if r.Method == SPIDE_GET { - switch r.URL.Path { - case ice.PS: - if repos == ice.VOLCANOS { - if s := msg.Cmdx("web.chat.website", lex.PARSE, ice.INDEX_IML, "Header", "", "River", "", "Footer", ""); s != "" { - Render(msg, ice.RENDER_RESULT, s) - return true // 定制主页 - } - } - Render(msg, ice.RENDER_DOWNLOAD, path.Join(msg.Config(kit.Keys(repos, nfs.PATH)), msg.Config(kit.Keys(repos, INDEX)))) - return true // 默认主页 + if r.Method != SPIDE_GET { + return false + } - case PP(ice.HELP): - r.URL.Path = P(ice.HELP, ice.TUTOR_SHY) - } - p := path.Join(ice.USR, repos, r.URL.Path) - m.Debug("what %v", p) - if _, e := nfs.DiskFile.StatFile(p); e == nil { - m.Debug("what %v", p) - http.ServeFile(w, r, kit.Path(p)) - return true - } else if f, e := nfs.PackFile.OpenFile(p); e == nil { - defer f.Close() - m.Debug("what %v", p) - RenderType(w, p, "") - io.Copy(w, f) - return true + msg, repos := m.Spawn(SERVE, w, r), kit.Select(ice.INTSHELL, ice.VOLCANOS, strings.Contains(r.Header.Get(UserAgent), "Mozilla/5.0")) + switch r.URL.Path { + case ice.PS: + if repos == ice.VOLCANOS { + if s := msg.Cmdx("web.chat.website", lex.PARSE, ice.INDEX_IML, "Header", "", "River", "", "Footer", ""); s != "" { + Render(msg, ice.RENDER_RESULT, s) + return true // 定制主页 + } } + Render(msg, ice.RENDER_DOWNLOAD, path.Join(msg.Config(kit.Keys(repos, nfs.PATH)), msg.Config(kit.Keys(repos, INDEX)))) + return true // 默认主页 + + case PP(ice.HELP): + r.URL.Path = P(ice.HELP, ice.TUTOR_SHY) + } + + p := path.Join(ice.USR, repos, r.URL.Path) + if _, e := nfs.DiskFile.StatFile(p); e == nil { + http.ServeFile(w, r, kit.Path(p)) + return true + } else if f, e := nfs.PackFile.OpenFile(p); e == nil { + defer f.Close() + RenderType(w, p, "") + io.Copy(w, f) + return true } return false }) @@ -67,8 +66,8 @@ func _serve_domain(m *ice.Message) string { if p := m.R.Header.Get("X-Host"); p != "" { return p } - if m.R.Method == "POST" { - if p := m.R.Header.Get("Referer"); p != "" { + if m.R.Method == SPIDE_POST { + if p := m.R.Header.Get(Referer); p != "" { return p } } @@ -190,7 +189,7 @@ func _serve_params(msg *ice.Message, path string) { } func _serve_handle(key string, cmd *ice.Command, msg *ice.Message, w http.ResponseWriter, r *http.Request) { // 地址参数 - if u, e := url.Parse(r.Header.Get("Referer")); e == nil { + if u, e := url.Parse(r.Header.Get(Referer)); e == nil { _serve_params(msg, u.Path) for k, v := range u.Query() { msg.Logs("refer", k, v) @@ -205,7 +204,7 @@ func _serve_handle(key string, cmd *ice.Command, msg *ice.Message, w http.Respon defer r.Body.Close() var data ice.Any if e := json.NewDecoder(r.Body).Decode(&data); !msg.Warn(e, ice.ErrNotFound, data) { - msg.Log_IMPORT(mdb.VALUE, kit.Format(data)) + msg.Logs(mdb.IMPORT, mdb.VALUE, kit.Format(data)) msg.Optionv(ice.MSG_USERDATA, data) } kit.Fetch(data, func(key string, value ice.Any) { msg.Optionv(key, value) }) @@ -304,14 +303,14 @@ func _serve_login(msg *ice.Message, key string, cmds []string, w http.ResponseWr return cmds, msg.Result(0) != ice.ErrWarn && msg.Result(0) != ice.FALSE } - if msg.Right(key, cmds) { + if aaa.Right(msg, key, cmds) { return cmds, true } if msg.Warn(msg.Option(ice.MSG_USERNAME) == "", ice.ErrNotLogin, r.URL.Path) { msg.Render(STATUS, http.StatusUnauthorized, ice.ErrNotLogin) return cmds, false // 未登录 - } else if !msg.Right(r.URL.Path) { + } else if !aaa.Right(msg, r.URL.Path) { msg.Render(STATUS, http.StatusForbidden, ice.ErrNotRight) return cmds, false // 未授权 } @@ -352,22 +351,22 @@ func init() { DOMAIN: {Name: "domain", Help: "域名", Hand: func(m *ice.Message, arg ...string) { ice.Info.Domain = m.Conf(SHARE, kit.Keym(DOMAIN, m.Config(DOMAIN, arg[0]))) }}, - cli.START: {Name: "start dev proto=http host port=9020 nodename password username userrole staffname", Help: "启动", Hand: func(m *ice.Message, arg ...string) { - _serve_start(m) - }}, SPIDE: {Name: "spide", Help: "架构图", Hand: func(m *ice.Message, arg ...string) { if len(arg) == 0 { // 模块列表 _serve_spide(m, ice.PS, m.Target()) - m.DisplayStorySpide(lex.PREFIX, m.ActionKey(), nfs.ROOT, m.MergeLink(ice.PS)) + ctx.DisplayStorySpide(m, lex.PREFIX, m.ActionKey(), nfs.ROOT, MergeLink(m, ice.PS)) } }}, - }, mdb.HashAction())}, + cli.START: {Name: "start dev proto=http host port=9020 nodename password username userrole staffname", Help: "启动", Hand: func(m *ice.Message, arg ...string) { + _serve_start(m) + }}, + }, mdb.HashAction(mdb.SHORT, mdb.NAME, mdb.FIELD, "time,status,name,proto,host,port,dev"))}, PP(ice.INTSHELL): {Name: "/intshell/", Help: "命令行", Hand: func(m *ice.Message, arg ...string) { - m.RenderIndex(SERVE, ice.INTSHELL, arg...) + RenderIndex(m, SERVE, ice.INTSHELL, arg...) }}, PP(ice.VOLCANOS): {Name: "/volcanos/", Help: "浏览器", Hand: func(m *ice.Message, arg ...string) { - m.RenderIndex(SERVE, ice.VOLCANOS, arg...) + RenderIndex(m, SERVE, ice.VOLCANOS, arg...) }}, PP(ice.PUBLISH): {Name: "/publish/", Help: "定制化", Hand: func(m *ice.Message, arg ...string) { _share_local(aaa.UserRoot(m), ice.USR_PUBLISH, path.Join(arg...)) @@ -375,27 +374,25 @@ func init() { PP(ice.REQUIRE): {Name: "/require/shylinux.com/x/volcanos/proto.js", Help: "代码库", Hand: func(m *ice.Message, arg ...string) { _share_repos(m, path.Join(arg[0], arg[1], arg[2]), arg[3:]...) }}, - PP(ice.REQUIRE, ice.SRC): {Name: "/require/src/", Help: "源代码", Hand: func(m *ice.Message, arg ...string) { - _share_local(aaa.UserRoot(m), ice.SRC, path.Join(arg...)) - }}, - PP(ice.REQUIRE, ice.USR): {Name: "/require/usr/", Help: "代码库", Hand: func(m *ice.Message, arg ...string) { - _share_local(aaa.UserRoot(m), ice.USR, path.Join(arg...)) - }}, PP(ice.REQUIRE, ice.NODE_MODULES): {Name: "/require/node_modules/", Help: "依赖库", Hand: func(m *ice.Message, arg ...string) { p := path.Join(ice.USR_VOLCANOS, ice.NODE_MODULES, path.Join(arg...)) - if b, ok := ice.Info.Pack[p]; ok && len(b) > 0 { - - } else if _, e := os.Stat(p); e != nil { + if !nfs.ExistsFile(m, p) { m.Cmd(cli.SYSTEM, "npm", "install", arg[0], kit.Dict(cli.CMD_DIR, ice.USR_VOLCANOS)) } m.RenderDownload(p) }}, + PP(ice.REQUIRE, ice.USR): {Name: "/require/usr/", Help: "代码库", Hand: func(m *ice.Message, arg ...string) { + _share_local(aaa.UserRoot(m), ice.USR, path.Join(arg...)) + }}, + PP(ice.REQUIRE, ice.SRC): {Name: "/require/src/", Help: "源代码", Hand: func(m *ice.Message, arg ...string) { + _share_local(aaa.UserRoot(m), ice.SRC, path.Join(arg...)) + }}, PP(ice.HELP): {Name: "/help/", Help: "帮助", Hand: func(m *ice.Message, arg ...string) { if len(arg) == 0 { - arg = append(arg, "tutor.shy") + arg = append(arg, ice.TUTOR_SHY) } if len(arg) > 0 && arg[0] != ctx.ACTION { - arg[0] = "src/help/" + arg[0] + arg[0] = path.Join(ice.SRC_HELP, arg[0]) } m.Cmdy("web.chat./cmd/", arg) }}, diff --git a/base/web/share.go b/base/web/share.go index 001dc06b..d6a45894 100644 --- a/base/web/share.go +++ b/base/web/share.go @@ -10,6 +10,7 @@ import ( ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/aaa" "shylinux.com/x/icebergs/base/cli" + "shylinux.com/x/icebergs/base/ctx" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" "shylinux.com/x/icebergs/base/ssh" @@ -35,10 +36,10 @@ func _share_render(m *ice.Message, arg ...string) { } func _share_link(m *ice.Message, p string, arg ...ice.Any) string { p = kit.Select("", SHARE_LOCAL, !strings.HasPrefix(p, ice.PS)) + p - return tcp.ReplaceLocalhost(m, m.MergeURL2(p, arg...)) + return tcp.ReplaceLocalhost(m, MergeURL2(m, p, arg...)) } func _share_cache(m *ice.Message, arg ...string) { - if pod := m.Option(ice.POD); m.PodCmd(CACHE, arg[0]) { + if pod := m.Option(ice.POD); ctx.PodCmd(m, CACHE, arg[0]) { if m.Append(nfs.FILE) == "" { m.RenderResult(m.Append(mdb.TEXT)) } else { @@ -59,7 +60,7 @@ func _share_local(m *ice.Message, arg ...string) { return // 没有权限 } default: - if !m.Right(ls) { + if !aaa.Right(m, ls) { m.Render(STATUS, http.StatusUnauthorized, ice.ErrNotRight) return // 没有权限 } @@ -78,9 +79,9 @@ func _share_local(m *ice.Message, arg ...string) { // 上传文件 if p == "bin/ice.bin" { - aaa.UserRoot(m).Cmd(SPACE, m.Option(ice.POD), SPIDE, "submit", m.MergeURL2(SHARE_PROXY, nfs.PATH, ""), m.Option(ice.POD), p, size, cache.Format(ice.MOD_TIME)) + aaa.UserRoot(m).Cmd(SPACE, m.Option(ice.POD), SPIDE, "submit", MergeURL2(m, SHARE_PROXY, nfs.PATH, ""), m.Option(ice.POD), p, size, cache.Format(ice.MOD_TIME)) } else { - m.Cmd(SPACE, m.Option(ice.POD), SPIDE, ice.DEV, SPIDE_RAW, m.MergeURL2(SHARE_PROXY, nfs.PATH, ""), + m.Cmd(SPACE, m.Option(ice.POD), SPIDE, ice.DEV, SPIDE_RAW, MergeURL2(m, SHARE_PROXY, nfs.PATH, ""), SPIDE_PART, m.OptionSimple(ice.POD), nfs.PATH, p, nfs.SIZE, size, CACHE, cache.Format(ice.MOD_TIME), UPLOAD, "@"+p) } if s, e := file.StatFile(pp); e == nil && !s.IsDir() { @@ -101,11 +102,11 @@ func _share_proxy(m *ice.Message) { } } func _share_repos(m *ice.Message, repos string, arg ...string) { - if repos == ice.Info.Make.Module && kit.FileExists(path.Join(arg...)) { + if repos == ice.Info.Make.Module && nfs.ExistsFile(m, path.Join(arg...)) { m.RenderDownload(path.Join(arg...)) return } - if !kit.FileExists(path.Join(ice.ISH_PLUGED, repos)) { // 克隆代码 + if !nfs.ExistsFile(m, path.Join(ice.ISH_PLUGED, repos)) { // 克隆代码 m.Cmd("web.code.git.repos", mdb.CREATE, nfs.REPOS, "https://"+repos, nfs.PATH, path.Join(ice.ISH_PLUGED, repos)) } m.RenderDownload(path.Join(ice.ISH_PLUGED, repos, path.Join(arg...))) @@ -132,14 +133,11 @@ const SHARE = "share" func init() { Index.MergeCommands(ice.Commands{ SHARE: {Name: "share hash auto prunes", Help: "共享链", Actions: ice.MergeAction(ice.Actions{ - ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { - _share_render(m) - }}, + ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { _share_render(m) }}, mdb.CREATE: {Name: "create type name text", Help: "创建", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(mdb.INSERT, m.PrefixKey(), "", mdb.HASH, mdb.TIME, m.Time(m.Config(mdb.EXPIRE)), - aaa.USERROLE, m.Option(ice.MSG_USERROLE), aaa.USERNAME, m.Option(ice.MSG_USERNAME), aaa.USERNICK, m.Option(ice.MSG_USERNICK), + mdb.HashCreate(m, aaa.USERROLE, m.Option(ice.MSG_USERROLE), aaa.USERNAME, m.Option(ice.MSG_USERNAME), aaa.USERNICK, m.Option(ice.MSG_USERNICK), RIVER, m.Option(ice.MSG_RIVER), STORM, m.Option(ice.MSG_STORM), arg) - m.Option(mdb.LINK, _share_link(m, "/share/"+m.Result())) + m.Option(mdb.LINK, _share_link(m, PP(SHARE)+m.Result())) }}, LOGIN: {Name: "login userrole=void,tech username", Help: "登录", Hand: func(m *ice.Message, arg ...string) { msg := m.Cmd(SHARE, mdb.CREATE, mdb.TYPE, LOGIN, m.OptionSimple(aaa.USERROLE, aaa.USERNAME)) @@ -147,7 +145,7 @@ func init() { m.ProcessInner() }}, }, mdb.HashAction(mdb.FIELD, "time,hash,userrole,username,river,storm,type,name,text", mdb.EXPIRE, "72h")), Hand: func(m *ice.Message, arg ...string) { - if m.PodCmd(SHARE, arg) && m.Length() > 0 { + if ctx.PodCmd(m, SHARE, arg) && m.Length() > 0 { return } if mdb.HashSelect(m, arg...); len(arg) > 0 { @@ -161,16 +159,15 @@ func init() { }}, PP(SHARE): {Name: "/share/", Help: "共享链", Hand: func(m *ice.Message, arg ...string) { msg := m.Cmd(SHARE, m.Option(SHARE, kit.Select(m.Option(SHARE), arg, 0))) - if kit.Int(msg.Append(mdb.TIME)) < kit.Int(msg.FormatTime()) { + if kit.Int(msg.Append(mdb.TIME)) < kit.Int(msg.Time()) { m.RenderResult("共享超时") return } switch msg.Append(mdb.TYPE) { case LOGIN: - sessid := aaa.SessCreate(m, msg.Append(aaa.USERNAME)) - m.RenderRedirect(ice.PS, ice.MSG_SESSID, sessid) + m.RenderRedirect(ice.PS, ice.MSG_SESSID, aaa.SessCreate(m, msg.Append(aaa.USERNAME))) default: - m.RenderIndex(SERVE, ice.VOLCANOS) + RenderIndex(m, SERVE, ice.VOLCANOS) } }}, diff --git a/base/web/space.go b/base/web/space.go index bb979f06..2b9d0674 100644 --- a/base/web/space.go +++ b/base/web/space.go @@ -9,6 +9,7 @@ import ( ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/aaa" "shylinux.com/x/icebergs/base/cli" + "shylinux.com/x/icebergs/base/gdb" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/tcp" kit "shylinux.com/x/toolkits" @@ -55,18 +56,17 @@ func _space_dial(m *ice.Message, dev, name string, arg ...string) { m.Go(func() { frame := m.Target().Server().(*Frame) - ls := strings.Split(host, ":") + ls := strings.Split(host, ice.DF) args := kit.SimpleKV("type,name,host,port", proto, dev, ls[0], kit.Select("443", ls, 1)) - redial := m.Configm(REDIAL) + redial, _ := m.Configv(REDIAL).(ice.Map) a, b, c := kit.Int(redial["a"]), kit.Int(redial["b"]), kit.Int(redial["c"]) for i := 0; i >= 0 && i < c; i++ { msg := m.Spawn() msg.Cmd(tcp.CLIENT, tcp.DIAL, args, func(s net.Conn) { if s, _, e := websocket.NewClient(s, u, nil, kit.Int(redial["r"]), kit.Int(redial["w"])); !msg.Warn(e) { - msg.Option(mdb.TARGET, s) - msg.Log_CREATE(SPACE, dev, "retry", i, "uri", uri) - mdb.HashCreate(msg, kit.SimpleKV("", MASTER, dev, host)) + msg.Logs(mdb.CREATE, SPACE, dev, "retry", i, "uri", uri) + mdb.HashCreate(msg, kit.SimpleKV("", MASTER, dev, host), kit.Dict(mdb.TARGET, s)) defer mdb.HashRemove(msg, mdb.NAME, name) if i = 0; _space_handle(msg, true, frame, s, dev) { @@ -97,16 +97,12 @@ func _space_handle(m *ice.Message, safe bool, frame *Frame, c *websocket.Conn, n msg.Log("recv", "%v->%v %s %v", source, target, msg.Detailv(), msg.FormatMeta()) if len(target) == 0 { // 执行命令 - if msg.Option(ice.MSG_HANDLE) == ice.TRUE { // 异常请求 - msg.Debug("what %v %v", msg.FormatMeta(), msg.FormatStack(1, 100)) - continue - } if msg.Optionv(ice.MSG_HANDLE, ice.TRUE); safe { // 下行命令 msg.Option(ice.MSG_USERROLE, kit.Select(msg.Option(ice.MSG_USERROLE), msg.Cmd(aaa.USER, msg.Option(ice.MSG_USERNAME)).Append(aaa.USERROLE))) - if msg.Option(ice.MSG_USERROLE) == aaa.VOID && ice.Info.UserName == "demo" { - msg.Option(ice.MSG_USERROLE, aaa.TECH) + if msg.Option(ice.MSG_USERROLE) == aaa.VOID && ice.Info.UserName == aaa.TECH { + msg.Option(ice.MSG_USERROLE, aaa.TECH) // 演示空间 } - msg.Log_AUTH(aaa.USERROLE, msg.Option(ice.MSG_USERROLE), aaa.USERNAME, msg.Option(ice.MSG_USERNAME)) + msg.Logs(ice.LOG_AUTH, aaa.USERROLE, msg.Option(ice.MSG_USERROLE), aaa.USERNAME, msg.Option(ice.MSG_USERNAME)) msg.Go(func() { _space_exec(msg, source, target, c, name) }) continue } @@ -145,13 +141,13 @@ func _space_handle(m *ice.Message, safe bool, frame *Frame, c *websocket.Conn, n continue } else { // 接收响应 m.Sleep30ms() - res.Back(msg) + back(res, msg) } } return false } func _space_exec(msg *ice.Message, source, target []string, c *websocket.Conn, name string) { - if msg.Right(msg.Detailv()) { // 执行命令 + if aaa.Right(msg, msg.Detailv()) { // 执行命令 msg = msg.Cmd() } @@ -202,15 +198,13 @@ func _space_send(m *ice.Message, space string, arg ...string) { // 返回结果 m.Option(TIMEOUT, m.Config(kit.Keys(TIMEOUT, "c"))) - m.Call(m.Option("_async") == "", func(res *ice.Message) *ice.Message { - if frame.delSend(id); res != nil && m != nil { - return m.Cost(kit.Format("[%v]->%v %v %v", id, target, arg, m.Copy(res).FormatSize())) - } - return nil + call(m, m.Option("_async") == "", func(res *ice.Message) { + m.Cost(kit.Format("[%v]->%v %v %v", id, target, arg, m.Copy(res).FormatSize())) + frame.delSend(id) }) } func _space_fork(m *ice.Message) { - buffer := m.Configm(BUFFER) + buffer, _ := m.Configv(BUFFER).(ice.Map) if s, e := websocket.Upgrade(m.W, m.R, nil, kit.Int(buffer["r"]), kit.Int(buffer["w"])); m.Assert(e) { text := kit.Select(s.RemoteAddr().String(), m.Option(ice.MSG_USERADDR)) name := strings.ToLower(m.Option(mdb.NAME, kit.ReplaceAll(kit.Select(text, m.Option(mdb.NAME)), ".", "_", ":", "_"))) @@ -218,33 +212,34 @@ func _space_fork(m *ice.Message) { args := append([]string{mdb.TYPE, kind, mdb.NAME, name}, m.OptionSimple(SHARE, RIVER)...) m.Go(func() { - m.Optionv(mdb.TARGET, s) - mdb.HashCreate(m, mdb.TEXT, kit.Select(text, m.Option(mdb.TEXT)), args) + mdb.HashCreate(m, mdb.TEXT, kit.Select(text, m.Option(mdb.TEXT)), args, kit.Dict(mdb.TARGET, s)) switch kind { case CHROME: // 交互节点 + gdb.Event(m, SPACE_OPEN, args...) + defer gdb.Event(m, SPACE_CLOSE, args...) defer mdb.HashRemove(m, mdb.NAME, name) m.Go(func(msg *ice.Message) { switch m.Option(ice.CMD) { case cli.PWD: link := kit.MergeURL(_space_domain(m), aaa.GRANT, name) msg.Sleep300ms(SPACE, name, cli.PWD, name, link, msg.Cmdx(cli.QRCODE, link)) - case "sso": + case SSO: link := _space_domain(m) ls := strings.Split(kit.ParseURL(link).Path, ice.PS) - link = kit.MergeURL2(_space_domain(m), "/chat/sso", "space", kit.Select("", ls, 3), "back", m.Option(ice.MSG_USERWEB)) + link = kit.MergeURL2(_space_domain(m), "/chat/sso", SPACE, kit.Select("", ls, 3), "back", m.Option(ice.MSG_USERWEB)) msg.Sleep300ms(SPACE, name, cli.PWD, name, link, msg.Cmdx(cli.QRCODE, link)) default: msg.Sleep300ms(SPACE, name, cli.PWD, name) } }) case WORKER: // 工作节点 - m.Event(DREAM_START, args...) - defer m.Event(DREAM_STOP, args...) + gdb.Event(m, DREAM_START, args...) + defer gdb.Event(m, DREAM_STOP, args...) defer m.Cmd(DREAM, DREAM_STOP, args) default: // 服务节点 - m.Event(SPACE_START, args...) - defer m.Event(SPACE_STOP, args...) + gdb.Event(m, SPACE_START, args...) + defer gdb.Event(m, SPACE_STOP, args...) defer mdb.HashRemove(m, mdb.NAME, name) } _space_handle(m, false, m.Target().Server().(*Frame), s, name) @@ -256,14 +251,12 @@ func _space_search(m *ice.Message, kind, name, text string, arg ...string) { if !strings.Contains(value[mdb.NAME], name) { return } - switch value[mdb.TYPE] { case CHROME: - case MASTER: - m.PushSearch(mdb.TEXT, m.Cmd(SPIDE, value[mdb.NAME], ice.OptionFields("")).Append("client.url"), value) + m.PushSearch(mdb.TEXT, m.CmdAppend(SPIDE, value[mdb.NAME], CLIENT_URL), value) default: - m.PushSearch(mdb.TEXT, m.MergePod(value[mdb.NAME]), value) + m.PushSearch(mdb.TEXT, MergePod(m, value[mdb.NAME]), value) } }) if name != "" { @@ -289,6 +282,8 @@ const ( REDIAL = "redial" TIMEOUT = "timeout" + SPACE_OPEN = "space.open" + SPACE_CLOSE = "space.close" SPACE_START = "space.start" SPACE_STOP = "space.stop" ) @@ -303,17 +298,7 @@ func init() { )}, }, Commands: ice.Commands{ SPACE: {Name: "space name cmd auto invite", Help: "空间站", Actions: ice.MergeAction(ice.Actions{ - ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { - m.Conf("", mdb.HASH, "") - }}, - ice.CTX_EXIT: {Hand: func(m *ice.Message, arg ...string) { - mdb.HashSelectValue(m, func(target ice.Any) { - if c, ok := target.(*websocket.Conn); ok { - c.Close() - } - }) - m.Conf("", mdb.HASH, "") - }}, + ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { m.Conf("", mdb.HASH, "") }}, mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) { mdb.HashModify(m, m.OptionSimple(mdb.NAME), mdb.STATUS, cli.STOP) defer mdb.HashRemove(m, m.OptionSimple(mdb.NAME)) @@ -337,15 +322,15 @@ func init() { DOMAIN: {Name: "domain", Help: "域名", Hand: func(m *ice.Message, arg ...string) { m.Echo(_space_domain(m)) }}, - }, mdb.HashAction()), Hand: func(m *ice.Message, arg ...string) { + }, mdb.HashCloseAction()), Hand: func(m *ice.Message, arg ...string) { if len(arg) < 2 { // 节点列表 if mdb.HashSelect(m, arg...); len(arg) == 0 { m.Tables(func(value ice.Maps) { switch value[mdb.TYPE] { case MASTER: - m.PushAnchor(value[mdb.NAME], m.Cmd(SPIDE, value[mdb.NAME], ice.OptionFields("")).Append("client.url")) + m.PushAnchor(value[mdb.NAME], m.CmdAppend(SPIDE, value[mdb.NAME], CLIENT_URL)) default: - m.PushAnchor(value[mdb.NAME], m.MergePod(value[mdb.NAME])) + m.PushAnchor(value[mdb.NAME], MergePod(m, value[mdb.NAME])) } }) m.Sort("type,name,text") @@ -360,3 +345,39 @@ func init() { }}, }}) } +func Space(m *ice.Message, arg ice.Any) []string { + if arg == nil || arg == "" || kit.Format(arg) == ice.Info.NodeName { + return nil + } + return []string{SPACE, kit.Format(arg)} +} + +func call(m *ice.Message, sync bool, cb func(*ice.Message)) { + wait := make(chan bool, 2) + + p := kit.Select("10s", m.Option(TIMEOUT)) + t := time.AfterFunc(kit.Duration(p), func() { + m.Warn(true, ice.ErrNotValid, m.Detailv()) + back(m, nil) + wait <- false + }) + + m.Optionv("_cb", func(res *ice.Message) { + if cb(res); sync { + wait <- true + t.Stop() + } + }) + + if sync { + <-wait + } else { + t.Stop() + } +} +func back(m *ice.Message, res *ice.Message) { + switch cb := m.Optionv("_cb").(type) { + case func(*ice.Message): + cb(res) + } +} diff --git a/base/web/spide.go b/base/web/spide.go index fab6d81b..d48d1342 100644 --- a/base/web/spide.go +++ b/base/web/spide.go @@ -24,11 +24,10 @@ import ( func _spide_create(m *ice.Message, name, address string) { if uri, e := url.Parse(address); !m.Warn(e != nil || address == "") { + m.Logs(mdb.CREATE, SPIDE, name, ADDRESS, address) dir, file := path.Split(uri.EscapedPath()) mdb.HashCreate(m, CLIENT_NAME, name) mdb.HashSelectUpdate(m, name, func(value ice.Map) { - value[SPIDE_COOKIE] = kit.Dict() - value[SPIDE_HEADER] = kit.Dict() value[SPIDE_CLIENT] = kit.Dict( mdb.NAME, name, SPIDE_METHOD, SPIDE_POST, "url", address, tcp.PROTOCOL, uri.Scheme, tcp.HOSTNAME, uri.Host, @@ -36,13 +35,11 @@ func _spide_create(m *ice.Message, name, address string) { cli.TIMEOUT, "600s", LOGHEADERS, ice.FALSE, ) }) - m.Log_CREATE(SPIDE, name, ADDRESS, address) } } func _spide_list(m *ice.Message, arg ...string) { - // 缓存方法 cache, save := "", "" - switch arg[1] { + switch arg[1] { // 缓存方法 case SPIDE_RAW: cache, arg = arg[1], arg[1:] case SPIDE_MSG: @@ -53,10 +50,9 @@ func _spide_list(m *ice.Message, arg ...string) { cache, arg = arg[1], arg[1:] } - // 请求方法 msg := mdb.HashSelect(m.Spawn(), arg[0]) method := kit.Select(SPIDE_POST, msg.Append(CLIENT_METHOD)) - switch arg = arg[1:]; arg[0] { + switch arg = arg[1:]; arg[0] { // 请求方法 case SPIDE_GET: method, arg = SPIDE_GET, arg[1:] case SPIDE_PUT: @@ -81,7 +77,7 @@ func _spide_list(m *ice.Message, arg ...string) { }) // 发送请求 - res, e := _spide_send(m, req, kit.Format(msg.Append("client.timeout"))) + res, e := _spide_send(m, msg.Append(CLIENT_NAME), req, kit.Format(msg.Append(CLIENT_TIMEOUT))) if m.Warn(e, ice.ErrNotFound, uri) { return } @@ -99,7 +95,7 @@ func _spide_list(m *ice.Message, arg ...string) { mdb.HashSelectUpdate(m, msg.Append(CLIENT_NAME), func(value ice.Map) { for _, v := range res.Cookies() { kit.Value(value, kit.Keys(SPIDE_COOKIE, v.Name), v.Value) - m.Log_IMPORT(v.Name, v.Value) + m.Logs(mdb.IMPORT, v.Name, v.Value) } }) @@ -162,7 +158,7 @@ func _spide_body(m *ice.Message, method string, arg ...string) (io.Reader, ice.M head[ContentType] = ContentJSON body = bytes.NewBuffer(b) } - m.Log_EXPORT(SPIDE_JSON, kit.Format(data)) + m.Logs(mdb.EXPORT, SPIDE_JSON, kit.Format(data)) } arg = arg[:0] } else { @@ -187,17 +183,17 @@ func _spide_part(m *ice.Message, arg ...string) (io.Reader, string) { } } if strings.HasPrefix(arg[i+1], "@") { - if s, e := os.Stat(arg[i+1][1:]); e == nil { - m.Debug("local: %s size: %d size: %d cache: %s", s.ModTime(), s.Size(), size, cache) + if s, e := nfs.StatFile(m, arg[i+1][1:]); e == nil { + m.Logs(mdb.IMPORT, "local", s.ModTime(), nfs.SIZE, s.Size(), CACHE, cache, nfs.SIZE, size) if s.Size() == size && s.ModTime().Before(cache) { // break } } - if f, e := os.Open(arg[i+1][1:]); m.Assert(e) { + if f, e := nfs.OpenFile(m, arg[i+1][1:]); m.Assert(e) { defer f.Close() if p, e := mp.CreateFormFile(arg[i], path.Base(arg[i+1][1:])); m.Assert(e) { if n, e := io.Copy(p, f); m.Assert(e) { - m.Debug("upload: %s %d", arg[i+1], n) + m.Logs(mdb.EXPORT, nfs.FILE, arg[i+1], nfs.SIZE, n) } } } @@ -235,12 +231,9 @@ func _spide_head(m *ice.Message, req *http.Request, head ice.Maps, value ice.Map m.Logs(req.Header.Get(ContentLength), req.Header.Get(ContentType)) } } -func _spide_send(m *ice.Message, req *http.Request, timeout string) (*http.Response, error) { - web := m.Target().Server().(*Frame) - if web.Client == nil { - web.Client = &http.Client{Timeout: kit.Duration(timeout)} - } - return web.Client.Do(req) +func _spide_send(m *ice.Message, name string, req *http.Request, timeout string) (*http.Response, error) { + client := mdb.HashTarget(m, name, func() ice.Any { return &http.Client{Timeout: kit.Duration(timeout)} }).(*http.Client) + return client.Do(req) } func _spide_save(m *ice.Message, cache, save, uri string, res *http.Response) { switch cache { @@ -263,11 +256,11 @@ func _spide_save(m *ice.Message, cache, save, uri string, res *http.Response) { m.Resultv(data[ice.MSG_RESULT]) case SPIDE_SAVE: - if f, p, e := kit.Create(save); m.Assert(e) { + if f, p, e := nfs.CreateFile(m, save); m.Assert(e) { defer f.Close() if n, e := io.Copy(f, res.Body); m.Assert(e) { - m.Log_EXPORT(nfs.SIZE, n, nfs.FILE, p) + m.Logs(mdb.EXPORT, nfs.SIZE, n, nfs.FILE, p) m.Echo(p) } } @@ -322,14 +315,15 @@ const ( ContentType = "Content-Type" ContentLength = "Content-Length" UserAgent = "User-Agent" + Referer = "Referer" Accept = "Accept" // 数据格式 ContentFORM = "application/x-www-form-urlencoded" ContentJSON = "application/json" + ContentPNG = "image/png" ContentHTML = "text/html" ContentCSS = "text/css" - ContentPNG = "image/png" ) const ( SPIDE_CLIENT = "client" @@ -337,10 +331,11 @@ const ( SPIDE_HEADER = "header" SPIDE_COOKIE = "cookie" - CLIENT_NAME = "client.name" - CLIENT_METHOD = "client.method" - CLIENT_URL = "client.url" - LOGHEADERS = "logheaders" + CLIENT_NAME = "client.name" + CLIENT_METHOD = "client.method" + CLIENT_TIMEOUT = "client.timeout" + CLIENT_URL = "client.url" + LOGHEADERS = "logheaders" FORM = "form" ADDRESS = "address" @@ -366,7 +361,7 @@ func init() { _spide_create(m, m.Option(mdb.NAME), m.Option(ADDRESS)) }}, MERGE: {Name: "merge name path", Help: "拼接", Hand: func(m *ice.Message, arg ...string) { - m.Echo(kit.MergeURL2(m.Cmd(SPIDE, arg[0], ice.OptionFields("")).Append(CLIENT_URL), arg[1], arg[2:])) + m.Echo(kit.MergeURL2(m.CmdAppend(SPIDE, arg[0], CLIENT_URL), arg[1], arg[2:])) }}, SUBMIT: {Name: "submit dev pod path size cache", Help: "发布", Hand: func(m *ice.Message, arg ...string) { m.Cmdy(SPIDE, ice.DEV, SPIDE_RAW, m.Option(ice.DEV), SPIDE_PART, m.OptionSimple(ice.POD), nfs.PATH, ice.BIN_ICE_BIN, UPLOAD, "@"+ice.BIN_ICE_BIN) @@ -381,6 +376,9 @@ func init() { SPIDE_GET: {Name: "GET url key value run", Help: "蜘蛛侠", Hand: func(m *ice.Message, arg ...string) { m.Echo(kit.Formats(kit.UnMarshal(m.Cmdx(SPIDE, ice.DEV, SPIDE_RAW, SPIDE_GET, arg[0], arg[1:])))) }}, + SPIDE_PUT: {Name: "PUT url key value run", Help: "蜘蛛侠", Hand: func(m *ice.Message, arg ...string) { + m.Echo(kit.Formats(kit.UnMarshal(m.Cmdx(SPIDE, ice.DEV, SPIDE_RAW, SPIDE_PUT, arg[0], arg[1:])))) + }}, SPIDE_POST: {Name: "POST url key value run", Help: "蜘蛛侠", Hand: func(m *ice.Message, arg ...string) { m.Echo(kit.Formats(kit.UnMarshal(m.Cmdx(SPIDE, ice.DEV, SPIDE_RAW, SPIDE_POST, arg[0], arg[1:])))) }}, diff --git a/base/web/web.go b/base/web/web.go index 7531793b..d60f3952 100644 --- a/base/web/web.go +++ b/base/web/web.go @@ -7,6 +7,8 @@ import ( ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/cli" + "shylinux.com/x/icebergs/base/ctx" + "shylinux.com/x/icebergs/base/gdb" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" "shylinux.com/x/icebergs/base/tcp" @@ -21,7 +23,7 @@ type Frame struct { *http.Server *http.ServeMux - send map[string]*ice.Message + send ice.Messages lock task.Lock } @@ -49,7 +51,7 @@ func (frame *Frame) Spawn(m *ice.Message, c *ice.Context, arg ...string) ice.Ser return &Frame{} } func (frame *Frame) Begin(m *ice.Message, arg ...string) ice.Server { - frame.send = map[string]*ice.Message{} + frame.send = ice.Messages{} return frame } func (frame *Frame) Start(m *ice.Message, arg ...string) bool { @@ -83,7 +85,7 @@ func (frame *Frame) Start(m *ice.Message, arg ...string) bool { return } msg.Log(ROUTE, "%s <- %s", s.Name, k, meta) - ice.Info.Route[path.Join(list[s], k)] = ice.FileCmd(kit.FileLine(x.Hand, 300)) + ice.Info.Route[path.Join(list[s], k)] = ctx.FileCmd(kit.FileLine(x.Hand, 300)) frame.HandleFunc(k, func(frame http.ResponseWriter, r *http.Request) { m.TryCatch(msg.Spawn(), true, func(msg *ice.Message) { _serve_handle(k, x, msg, frame, r) @@ -93,17 +95,17 @@ func (frame *Frame) Start(m *ice.Message, arg ...string) bool { } }) - m.Event(SERVE_START) - defer m.Event(SERVE_STOP) + gdb.Event(m, SERVE_START) + defer gdb.Event(m, SERVE_STOP) frame.Message, frame.Server = m, &http.Server{Handler: frame} - switch cb := m.OptionCB(SERVE).(type) { + switch cb := m.OptionCB("").(type) { case func(http.Handler): cb(frame) // 启动框架 default: m.Cmd(tcp.SERVER, tcp.LISTEN, mdb.TYPE, WEB, m.OptionSimple(mdb.NAME, tcp.HOST, tcp.PORT), func(l net.Listener) { - m.Cmd(mdb.INSERT, SERVE, "", mdb.HASH, mdb.NAME, WEB, arg, m.OptionSimple(tcp.PROTO, ice.DEV), cli.STATUS, tcp.START, kit.Dict(mdb.TARGET, l)) - defer m.Cmd(mdb.MODIFY, SERVE, "", mdb.HASH, m.OptionSimple(mdb.NAME), cli.STATUS, tcp.STOP) + mdb.HashCreate(m, mdb.NAME, WEB, arg, m.OptionSimple(tcp.PROTO, ice.DEV), cli.STATUS, tcp.START, kit.Dict(mdb.TARGET, l)) + defer mdb.HashModify(m, m.OptionSimple(mdb.NAME), cli.STATUS, tcp.STOP) m.Warn(frame.Server.Serve(l)) // 启动服务 }) } @@ -113,12 +115,10 @@ func (frame *Frame) Close(m *ice.Message, arg ...string) bool { return true } -func P(arg ...string) string { return path.Join(ice.PS, path.Join(arg...)) } -func PP(arg ...string) string { return path.Join(ice.PS, path.Join(arg...)) + ice.PS } - const ( SERVE_START = "serve.start" SERVE_STOP = "serve.stop" + WEBSITE = "website" ) const WEB = "web" @@ -130,3 +130,6 @@ func init() { SHARE, CACHE, SPIDE, ROUTE, ) } + +func P(arg ...string) string { return path.Join(ice.PS, path.Join(arg...)) } +func PP(arg ...string) string { return P(arg...) + ice.PS } diff --git a/base/yac/matrix.go b/base/yac/matrix.go index fe6eabc4..f23a4544 100644 --- a/base/yac/matrix.go +++ b/base/yac/matrix.go @@ -310,11 +310,11 @@ func (mat *Matrix) show(m *ice.Message) { } func _yac_load(m *ice.Message) { - m.Richs(m.PrefixKey(), "", mdb.FOREACH, func(key string, value ice.Map) { + mdb.Richs(m, m.PrefixKey(), "", mdb.FOREACH, func(key string, value ice.Map) { value = kit.GetMeta(value) mat := NewMatrix(m, kit.Int(kit.Select("32", value[NLANG])), kit.Int(kit.Select("32", value[NCELL]))) - m.Grows(m.PrefixKey(), kit.Keys(mdb.HASH, key), "", "", func(index int, value ice.Map) { + mdb.Grows(m, m.PrefixKey(), kit.Keys(mdb.HASH, key), "", "", func(index int, value ice.Map) { page := mat.index(m, NPAGE, kit.Format(value[NPAGE])) hash := mat.index(m, NHASH, kit.Format(value[NHASH])) if mat.mat[page] == nil { @@ -351,7 +351,7 @@ func init() { ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { _yac_load(m) }}, mdb.CREATE: {Name: "create name=shy nlang=32 ncell=32", Help: "创建", Hand: func(m *ice.Message, arg ...string) { mat := NewMatrix(m, kit.Int(kit.Select("32", m.Option(NLANG))), kit.Int(kit.Select("32", m.Option(NCELL)))) - h := m.Rich(m.PrefixKey(), "", kit.Data( + h := mdb.Rich(m, m.PrefixKey(), "", kit.Data( mdb.TIME, m.Time(), mdb.NAME, m.Option(mdb.NAME), MATRIX, mat, NLANG, mat.nlang, NCELL, mat.ncell, )) @@ -364,7 +364,7 @@ func init() { m.Echo(h) }}, mdb.INSERT: {Name: "insert name=shy npage=num nhash=num text=123", Help: "添加", Hand: func(m *ice.Message, arg ...string) { - m.Richs(m.PrefixKey(), "", m.Option(mdb.NAME), func(key string, value ice.Map) { + mdb.Richs(m, m.PrefixKey(), "", m.Option(mdb.NAME), func(key string, value ice.Map) { value = kit.GetMeta(value) mat, _ := value[MATRIX].(*Matrix) @@ -378,7 +378,7 @@ func init() { m.Option(mdb.TEXT, strings.ReplaceAll(m.Option(mdb.TEXT), "\\", "\\\\")) text := kit.Split(m.Option(mdb.TEXT), " ", " ", " ") mat.train(m, page, hash, text, 1) - m.Grow(m.PrefixKey(), kit.Keys(mdb.HASH, key), kit.Dict( + mdb.Grow(m, m.PrefixKey(), kit.Keys(mdb.HASH, key), kit.Dict( mdb.TIME, m.Time(), NPAGE, m.Option(NPAGE), NHASH, m.Option(NHASH), mdb.TEXT, text, )) @@ -390,7 +390,7 @@ func init() { m.Cmdy(mdb.DELETE, m.PrefixKey(), "", mdb.HASH, mdb.NAME, m.Option(mdb.NAME)) }}, PARSE: {Name: "parse name npage text=123", Help: "解析", Hand: func(m *ice.Message, arg ...string) { - m.Richs(m.PrefixKey(), "", m.Option(mdb.NAME), func(key string, value ice.Map) { + mdb.Richs(m, m.PrefixKey(), "", m.Option(mdb.NAME), func(key string, value ice.Map) { value = kit.GetMeta(value) mat, _ := value[MATRIX].(*Matrix) @@ -413,14 +413,14 @@ func init() { m.ProcessInner() }}, "show": {Name: "show", Help: "矩阵", Hand: func(m *ice.Message, arg ...string) { - m.Richs(m.PrefixKey(), "", kit.Select(m.Option(mdb.NAME), arg, 0), func(key string, value ice.Map) { + mdb.Richs(m, m.PrefixKey(), "", kit.Select(m.Option(mdb.NAME), arg, 0), func(key string, value ice.Map) { value = kit.GetMeta(value) value[MATRIX].(*Matrix).show(m) }) m.ProcessInner() }}, }, Hand: func(m *ice.Message, arg ...string) { - m.Option(ice.CACHE_LIMIT, -1) + m.Option(mdb.CACHE_LIMIT, -1) if m.Action(mdb.CREATE); len(arg) == 0 { // 矩阵列表 m.Fields(len(arg), "time,name,npage,nhash") m.Cmdy(mdb.SELECT, m.PrefixKey(), "", mdb.HASH) @@ -436,7 +436,7 @@ func init() { } // 词法矩阵 - m.Richs(m.PrefixKey(), "", arg[0], func(key string, value ice.Map) { + mdb.Richs(m, m.PrefixKey(), "", arg[0], func(key string, value ice.Map) { value = kit.GetMeta(value) value[MATRIX].(*Matrix).show(m) }) diff --git a/conf.go b/conf.go index 8e691f9c..900c982f 100644 --- a/conf.go +++ b/conf.go @@ -17,10 +17,10 @@ const ( SUCCESS = "success" FAILURE = "failure" PROCESS = "process" - OF = " of " INIT = "init" EXIT = "exit" + QUIT = "quit" SAVE = "save" LOAD = "load" @@ -56,12 +56,7 @@ const ( const ( // MOD MOD_DIR = 0750 MOD_FILE = 0640 - - MOD_CHAN = 16 - MOD_TICK = "1s" MOD_BUFS = 4096 - - MOD_DATE = "2006-01-02" MOD_TIME = "2006-01-02 15:04:05" ) const ( // REPOS @@ -94,6 +89,20 @@ const ( // DIR CSV = "csv" JSON = "json" + FAVICON = "favicon.ico" + PROTO_JS = "proto.js" + FRAME_JS = "frame.js" + INDEX_JS = "index.js" + INDEX_SH = "index.sh" + INDEX_IML = "index.iml" + TUTOR_SHY = "tutor.shy" + + PLUGIN_INPUT = "/plugin/input" + PLUGIN_STORY = "/plugin/story" + PLUGIN_LOCAL = "/plugin/local" + NODE_MODULES = "node_modules" + ISH_PLUGED = ".ish/pluged" + USR_VOLCANOS = "usr/volcanos" USR_LEARNING = "usr/learning" USR_ICEBERGS = "usr/icebergs" @@ -103,22 +112,6 @@ const ( // DIR USR_RELEASE = "usr/release" USR_PUBLISH = "usr/publish" - PLUGIN_INPUT = "/plugin/input" - PLUGIN_STORY = "/plugin/story" - PLUGIN_LOCAL = "/plugin/local" - NODE_MODULES = "node_modules" - ISH_PLUGED = ".ish/pluged" - - FAVICON = "favicon.ico" - PROTO_JS = "proto.js" - FRAME_JS = "frame.js" - INDEX_JS = "index.js" - ORDER_JS = "order.js" - ORDER_SH = "order.sh" - INDEX_SH = "index.sh" - INDEX_IML = "index.iml" - TUTOR_SHY = "tutor.shy" - USR_LOCAL = "usr/local" USR_LOCAL_GO = "usr/local/go" USR_LOCAL_GO_BIN = "usr/local/go/bin" @@ -162,8 +155,6 @@ const ( // DIR ICE_BIN = "ice.bin" GO_SUM = "go.sum" GO_MOD = "go.mod" - - CTX_DAEMON = "ctx_daemon" ) const ( // MSG MSG_DETAIL = "detail" @@ -174,14 +165,14 @@ const ( // MSG MSG_CMDS = "cmds" MSG_FIELDS = "fields" MSG_SESSID = "sessid" - MSG_DOMAIN = "domain" - MSG_OPTS = "_option" - MSG_ALIAS = "_alias" - MSG_SCRIPT = "_script" + MSG_OPTS = "_option" MSG_SOURCE = "_source" MSG_TARGET = "_target" MSG_HANDLE = "_handle" + + MSG_ALIAS = "_alias" + MSG_SCRIPT = "_script" MSG_OUTPUT = "_output" MSG_ARGS = "_args" @@ -190,8 +181,8 @@ const ( // MSG MSG_ACTION = "_action" MSG_STATUS = "_status" - MSG_DISPLAY = "_display" MSG_PROCESS = "_process" + MSG_DISPLAY = "_display" MSG_USERIP = "user.ip" MSG_USERUA = "user.ua" @@ -209,28 +200,27 @@ const ( // MSG MSG_TOPIC = "sess.topic" MSG_RIVER = "sess.river" MSG_STORM = "sess.storm" - MSG_TOAST = "sess.toast" - MSG_LOCAL = "sess.local" - MSG_FILES = "file.system" + + FIELDS_DETAIL = "detail" ) const ( // RENDER + RENDER_TEMPLATE = "_template" + RENDER_ANCHOR = "_anchor" + RENDER_BUTTON = "_button" + RENDER_IMAGES = "_images" + RENDER_VIDEOS = "_videos" + RENDER_IFRAME = "_iframe" + RENDER_QRCODE = "_qrcode" + RENDER_SCRIPT = "_script" + RENDER_STATUS = "_status" RENDER_REDIRECT = "_redirect" RENDER_DOWNLOAD = "_download" - RENDER_TEMPLATE = "_template" RENDER_RESULT = "_result" RENDER_JSON = "_json" RENDER_VOID = "_void" RENDER_RAW = "_raw" - - RENDER_ANCHOR = "_anchor" - RENDER_BUTTON = "_button" - RENDER_SCRIPT = "_script" - RENDER_QRCODE = "_qrcode" - RENDER_IMAGES = "_images" - RENDER_VIDEOS = "_videos" - RENDER_IFRAME = "_iframe" ) const ( // PROCESS PROCESS_LOCATION = "_location" @@ -253,16 +243,6 @@ const ( // PROCESS FIELD_PREFIX = "_prefix" ) -const ( // CACHE - CACHE_LIMIT = "cache.limit" - CACHE_BEGIN = "cache.begin" - CACHE_COUNT = "cache.count" - CACHE_OFFEND = "cache.offend" - CACHE_FILTER = "cache.filter" - CACHE_VALUE = "cache.value" - CACHE_FIELD = "cache.field" - CACHE_DETAIL = "detail" -) const ( // CTX CTX_FOLLOW = "follow" CTX_STATUS = "status" @@ -275,37 +255,19 @@ const ( // CTX CTX_INIT = "_init" CTX_EXIT = "_exit" + + CTX_ARG = "ctx_arg" + CTX_DAEMON = "ctx_daemon" ) const ( // LOG - // 通用 - LOG_INFO = "info" + LOG_CMDS = "cmds" + LOG_AUTH = "auth" LOG_COST = "cost" + LOG_INFO = "info" LOG_WARN = "warn" - LOG_ERROR = "error" LOG_DEBUG = "debug" - - // 命令 - LOG_AUTH = "auth" - LOG_CMDS = "cmds" - LOG_SEND = "send" - LOG_RECV = "recv" - - // 状态 - LOG_BEGIN = "begin" - LOG_START = "start" - LOG_SERVE = "serve" - LOG_CLOSE = "close" - - // 数据 - LOG_CREATE = "create" - LOG_REMOVE = "remove" - LOG_INSERT = "insert" - LOG_DELETE = "delete" - LOG_MODIFY = "modify" - LOG_SELECT = "select" - LOG_EXPORT = "export" - LOG_IMPORT = "import" + LOG_ERROR = "error" ) const ( // Err ErrWarn = "warn: " @@ -318,72 +280,23 @@ const ( // Err ErrNotImplement = "not implement: " ) -const ( // ice - // CTX = "ctx" - CLI = "cli" - WEB = "web" - AAA = "aaa" - LEX = "lex" - YAC = "yac" - GDB = "gdb" - LOG = "log" - TCP = "tcp" - NFS = "nfs" - SSH = "ssh" - MDB = "mdb" -) const ( // ctx COMMAND = "command" ACTION = "action" - CONFIG = "config" STYLE = "style" INDEX = "index" - ARGS = "args" - INPUTS = "inputs" - FEATURE = "feature" -) -const ( // web - SERVE = "serve" - SPACE = "space" - SPIDE = "spide" - CACHE = "cache" - - WEBSITE = "website" -) -const ( // aaa - ROLE = "role" - RIGHT = "right" - USERROLE = "userrole" - ROOT = "root" ) const ( // mdb + MDB = "mdb" KEY = "key" VALUE = "value" + EXTRA = "extra" SCRIPT = "script" + META = "meta" + HASH = "hash" + TIME = "time" + TYPE = "type" + NAME = "name" + TEXT = "text" LINK = "link" - - META = "meta" - HASH = "hash" - TIME = "time" - TYPE = "type" - NAME = "name" - TEXT = "text" -) -const ( // ssh - SOURCE = "source" -) -const ( // gdb - EVENT = "event" - LISTEN = "listen" - HAPPEN = "happen" - FILELINE = "fileline" - - RESTART = "restart" - ERROR = "error" - OPEN = "open" - CLOSE = "close" - START = "start" - STOP = "stop" - BEGIN = "begin" - END = "end" ) diff --git a/core/chat/action.go b/core/chat/action.go index 7aab57ab..f4a6ed62 100644 --- a/core/chat/action.go +++ b/core/chat/action.go @@ -1,8 +1,6 @@ package chat import ( - "path" - ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/aaa" "shylinux.com/x/icebergs/base/ctx" @@ -14,9 +12,9 @@ import ( func _action_right(m *ice.Message, river string, storm string) (ok bool) { if ok = true; m.Option(ice.MSG_USERROLE) == aaa.VOID { - m.Richs(RIVER, "", river, func(key string, value ice.Map) { - if ok = m.Richs(RIVER, kit.Keys(mdb.HASH, key, OCEAN), m.Option(ice.MSG_USERNAME), nil) != nil; ok { - m.Log_AUTH(RIVER, river, STORM, storm) + mdb.Richs(m, RIVER, "", river, func(key string, value ice.Map) { + if ok = mdb.Richs(m, RIVER, kit.Keys(mdb.HASH, key, OCEAN), m.Option(ice.MSG_USERNAME), nil) != nil; ok { + m.Logs(ice.LOG_AUTH, RIVER, river, STORM, storm) } }) } @@ -27,7 +25,7 @@ func _action_key(m *ice.Message, arg ...string) string { } func _action_list(m *ice.Message, river, storm string) { m.Cmdy(STORM, storm, ice.Option{ice.MSG_RIVER, river}).Tables(func(value ice.Maps) { - m.Cmdy(m.Space(kit.Select(m.Option(ice.POD), value[ice.POD])), ctx.COMMAND, kit.Keys(value[ice.CTX], value[ice.CMD])) + m.Cmdy(web.Space(m, kit.Select(m.Option(ice.POD), value[ice.POD])), ctx.COMMAND, kit.Keys(value[ice.CTX], value[ice.CMD])) }) } func _action_exec(m *ice.Message, river, storm, index string, arg ...string) { @@ -35,19 +33,19 @@ func _action_exec(m *ice.Message, river, storm, index string, arg ...string) { m.Option(ice.MSG_STORM, storm) cmds := []string{index} - if m.Grows(RIVER, _action_key(m, river, storm), mdb.ID, index, func(index int, value ice.Map) { + if mdb.Grows(m, RIVER, _action_key(m, river, storm), mdb.ID, index, func(index int, value ice.Map) { if cmds = kit.Simple(kit.Keys(value[ice.CTX], value[ice.CMD])); kit.Format(value[ice.POD]) != "" { m.Option(ice.POD, value[ice.POD]) // 远程节点 } - }) == nil && m.Option(ice.MSG_USERPOD) == "" && !m.Right(cmds) { + }) == nil && m.Option(ice.MSG_USERPOD) == "" && !aaa.Right(m, cmds) { return // 没有授权 } - if _action_domain(m, cmds[0]); m.Option(ice.MSG_UPLOAD) != "" { + if m.Option(ice.MSG_UPLOAD) != "" { _action_upload(m) // 上传文件 } - if cmds[0] == "web.chat.node" || !m.PodCmd(cmds, arg) { + if cmds[0] == "web.chat.node" || !ctx.PodCmd(m, cmds, arg) { m.Cmdy(cmds, arg) // 执行命令 } } @@ -55,7 +53,7 @@ func _action_auth(m, msg *ice.Message) bool { if m.Warn(kit.Time() > kit.Time(msg.Append(mdb.TIME)), ice.ErrNotValid) { return false } - m.Log_AUTH( + m.Logs(ice.LOG_AUTH, aaa.USERROLE, m.Option(ice.MSG_USERROLE, msg.Append(aaa.USERROLE)), aaa.USERNAME, m.Option(ice.MSG_USERNAME, msg.Append(aaa.USERNAME)), aaa.USERNICK, m.Option(ice.MSG_USERNICK, msg.Append(aaa.USERNICK)), @@ -92,45 +90,13 @@ func _action_share(m *ice.Message, arg ...string) { break // 命令列表 } - if _action_domain(m, arg[1]); m.Option(ice.MSG_UPLOAD) != "" { + if m.Option(ice.MSG_UPLOAD) != "" { _action_upload(m) // 上传文件 } m.Cmdy(arg[1:]) // 执行命令 } } -func _action_domain(m *ice.Message, cmd string, arg ...string) (domain string) { - m.Option(ice.MSG_LOCAL, "") - m.Option(ice.MSG_DOMAIN, "") - if m.Config(kit.Keys(DOMAIN, cmd)) != ice.TRUE { - return "" // 公有命令 - } - - river := kit.Select(m.Option(ice.MSG_RIVER), arg, 0) - storm := kit.Select(m.Option(ice.MSG_STORM), arg, 1) - m.Richs(RIVER, "", river, func(key string, value ice.Map) { - switch kit.Value(kit.GetMeta(value), mdb.TYPE) { - case PUBLIC: // 公有群 - return - case PROTECTED: // 共有群 - m.Richs(RIVER, kit.Keys(mdb.HASH, river, STORM), storm, func(key string, value ice.Map) { - switch r := "R" + river; kit.Value(kit.GetMeta(value), mdb.TYPE) { - case PUBLIC: // 公有组 - domain = m.Option(ice.MSG_DOMAIN, kit.Keys(r)) - case PROTECTED: // 共有组 - domain = m.Option(ice.MSG_DOMAIN, kit.Keys(r, "S"+storm)) - case PRIVATE: // 私有组 - domain = m.Option(ice.MSG_DOMAIN, kit.Keys(r, "U"+m.Option(ice.MSG_USERNAME))) - } - }) - case PRIVATE: // 私有群 - domain = m.Option(ice.MSG_DOMAIN, kit.Keys("U"+m.Option(ice.MSG_USERNAME))) - } - m.Option(ice.MSG_LOCAL, path.Join(m.Config(nfs.PATH), domain)) - }) - m.Log_AUTH(RIVER, river, STORM, storm, DOMAIN, domain) - return -} func _action_upload(m *ice.Message) { msg := m.Cmd(web.CACHE, web.UPLOAD) m.Option(ice.MSG_UPLOAD, msg.Append(mdb.HASH), msg.Append(mdb.NAME), msg.Append(nfs.SIZE)) diff --git a/core/chat/cmd.go b/core/chat/cmd.go index 72bc4136..3984fff9 100644 --- a/core/chat/cmd.go +++ b/core/chat/cmd.go @@ -15,14 +15,14 @@ import ( func _cmd_file(m *ice.Message, arg ...string) bool { switch p := path.Join(arg...); kit.Ext(p) { case nfs.JS: - m.Display(ice.FileURI(p)) - m.RenderCmd(kit.Select(ctx.CAN_PLUGIN, ice.GetFileCmd(p))) + m.Display(ctx.FileURI(p)) + web.RenderCmd(m, kit.Select(ctx.CAN_PLUGIN, ctx.GetFileCmd(p))) case nfs.GO: - m.RenderCmd(ice.GetFileCmd(p)) + web.RenderCmd(m, ctx.GetFileCmd(p)) case nfs.SHY: - m.RenderCmd("web.wiki.word", p) + web.RenderCmd(m, "web.wiki.word", p) case nfs.IML: if m.Option(ice.MSG_USERPOD) == "" { @@ -34,7 +34,7 @@ func _cmd_file(m *ice.Message, arg ...string) bool { } case nfs.ZML: - m.RenderCmd("can.parse", m.Cmdx(nfs.CAT, p)) + web.RenderCmd(m, "can.parse", m.Cmdx(nfs.CAT, p)) default: if p = strings.TrimPrefix(p, ice.SRC+ice.PS); kit.FileExists(path.Join(ice.SRC, p)) { @@ -54,7 +54,7 @@ func init() { Index.MergeCommands(ice.Commands{ CMD: {Name: "cmd path auto upload up home", Help: "命令", Actions: ice.MergeAction(ice.Actions{ web.UPLOAD: {Name: "upload", Help: "上传", Hand: func(m *ice.Message, arg ...string) { - m.Upload(path.Join(m.Config(nfs.PATH), strings.TrimPrefix(path.Dir(m.R.URL.Path), "/cmd"))) + m.Cmdy(web.CACHE, web.UPLOAD_WATCH, path.Join(m.Config(nfs.PATH), strings.TrimPrefix(path.Dir(m.R.URL.Path), "/cmd"))) }}, "home": {Name: "home", Help: "根目录", Hand: func(m *ice.Message, arg ...string) { @@ -74,7 +74,7 @@ func init() { return } if msg := m.Cmd(ctx.COMMAND, arg[0]); msg.Length() > 0 { - m.RenderCmd(arg[0]) + web.RenderCmd(m, arg[0]) return } @@ -98,19 +98,19 @@ func init() { }}, }, ctx.CmdAction()), Hand: func(m *ice.Message, arg ...string) { if strings.HasSuffix(m.R.URL.Path, ice.PS) { - m.RenderCmd(CMD) + web.RenderCmd(m, CMD) return // 目录 } if _cmd_file(m, arg...) { return } - if m.PodCmd(ctx.COMMAND, arg[0]) { + if ctx.PodCmd(m, ctx.COMMAND, arg[0]) { if !m.IsErr() { - m.RenderCmd(arg[0], arg[1:]) // 远程命令 + web.RenderCmd(m, arg[0], arg[1:]) // 远程命令 } } else if m.Cmdy(ctx.COMMAND, arg[0]); m.Length() > 0 { - m.RenderCmd(arg[0], arg[1:]) // 本地命令 + web.RenderCmd(m, arg[0], arg[1:]) // 本地命令 } else { m.RenderDownload(path.Join(m.Config(nfs.PATH), path.Join(arg...))) // 文件 } diff --git a/core/chat/div.go b/core/chat/div.go index b7f9108b..592e19cc 100644 --- a/core/chat/div.go +++ b/core/chat/div.go @@ -9,6 +9,7 @@ import ( "shylinux.com/x/icebergs/base/lex" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" + "shylinux.com/x/icebergs/base/web" kit "shylinux.com/x/toolkits" ) @@ -41,7 +42,7 @@ func init() { case nfs.JSON: m.RenderResult(_div_template2, kit.Format(kit.UnMarshal(m.Cmdx(nfs.CAT, p)))) default: - m.RenderCmd(m.PrefixKey(), p) + web.RenderCmd(m, m.PrefixKey(), p) } }}, DIV: {Name: "div hash auto import", Help: "定制", Actions: ice.MergeAction(ice.Actions{ @@ -74,11 +75,13 @@ func init() { switch kit.Ext(kit.Select("", arg, 0)) { case nfs.SHY: m.Fields(0) - m.Push(mdb.TEXT, _div_parse(m, m.Cmdx(nfs.CAT, arg[0]))).DisplayLocal("") + m.Push(mdb.TEXT, _div_parse(m, m.Cmdx(nfs.CAT, arg[0]))) + ctx.DisplayLocal(m, "") default: if mdb.HashSelect(m, arg...); len(arg) > 0 { - m.Action("添加", "保存").DisplayLocal("") - m.StatusTime(mdb.LINK, m.MergeLink("/chat/div/"+arg[0])) + m.Action("添加", "保存") + ctx.DisplayLocal(m, "") + m.StatusTime(mdb.LINK, web.MergeURL2(m, "/chat/div/"+arg[0])) } else { m.Action(lex.SPLIT, mdb.CREATE) } diff --git a/core/chat/header.go b/core/chat/header.go index d0bf4500..3c4606a0 100644 --- a/core/chat/header.go +++ b/core/chat/header.go @@ -136,7 +136,7 @@ func init() { m.Option(k, msg.Append(k)) } for _, k := range []string{aaa.AVATAR, aaa.BACKGROUND} { - m.Option(k, kit.Select(web.SHARE_LOCAL+k, kit.Select("void", msg.Append(k)), m.Right(msg.Append(k)))) + m.Option(k, kit.Select(web.SHARE_LOCAL+k, kit.Select("void", msg.Append(k)), aaa.Right(m, msg.Append(k)))) } if m.Option(aaa.AVATAR) == "" && m.R.Header.Get("Staffname") != "" { m.Option(aaa.AVATAR, kit.Format("https://dayu.oa.com/avatars/%s/profile.jpg", m.R.Header.Get("Staffname"))) diff --git a/core/chat/location.go b/core/chat/location.go index e0fb0378..5fe3b6fe 100644 --- a/core/chat/location.go +++ b/core/chat/location.go @@ -55,7 +55,7 @@ func init() { }}, }, mdb.HashAction(mdb.FIELD, "time,hash,type,name,text,latitude,longitude,extra"), ctx.CmdAction()), Hand: func(m *ice.Message, arg ...string) { mdb.HashSelect(m, kit.Slice(arg, 0, 1)...) - m.DisplayLocal("", m.ConfigSimple(aaa.TOKEN)) + ctx.DisplayLocal(m, "", m.ConfigSimple(aaa.TOKEN)) m.Option(LOCATION, get(m, "location/v1/ip", aaa.IP, m.Option(ice.MSG_USERIP))) }}, }) diff --git a/core/chat/node.go b/core/chat/node.go index 2c7d961d..4f00bb23 100644 --- a/core/chat/node.go +++ b/core/chat/node.go @@ -3,6 +3,7 @@ package chat import ( ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/aaa" + "shylinux.com/x/icebergs/base/gdb" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/web" "shylinux.com/x/icebergs/core/code" @@ -15,8 +16,8 @@ func init() { Index.MergeCommands(ice.Commands{ NODE: {Name: "node pod ctx cmd auto insert invite", Help: "设备", Actions: ice.Actions{ ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { - m.Watch(web.DREAM_START, m.PrefixKey()) - m.Watch(web.SPACE_START, m.PrefixKey()) + gdb.Watch(m, web.DREAM_START, m.PrefixKey()) + gdb.Watch(m, web.SPACE_START, m.PrefixKey()) }}, web.SPACE_START: {Name: "start type name share river", Help: "启动", Hand: func(m *ice.Message, arg ...string) { if m.Option(ice.MSG_RIVER, m.Option(RIVER)) == "" { @@ -52,7 +53,7 @@ func init() { m.OptionFields("time,type,name,share") m.Cmdy(mdb.SELECT, RIVER, _river_key(m, NODE), mdb.HASH) m.Tables(func(value ice.Maps) { - m.PushAnchor(value[mdb.NAME], m.MergeURL2("/chat/pod/"+kit.Keys(m.Option(ice.POD), value[mdb.NAME]))) + m.PushAnchor(value[mdb.NAME], web.MergeURL2(m, "/chat/pod/"+kit.Keys(m.Option(ice.POD), value[mdb.NAME]))) }) m.RenameAppend("name", "pod") m.PushAction(mdb.REMOVE) diff --git a/core/chat/oauth/oauth.go b/core/chat/oauth/oauth.go index a13dafe3..2ff42d40 100644 --- a/core/chat/oauth/oauth.go +++ b/core/chat/oauth/oauth.go @@ -1,6 +1,7 @@ package oauth import ( + "path" "strings" "time" @@ -18,15 +19,15 @@ import ( func _merge_url(m *ice.Message, domain, key string, arg ...ice.Any) string { if domain == "" { if m.Option(ice.MSG_USERPOD) == "" { - domain = m.MergeLink(ice.PS) + domain = web.MergeLink(m, ice.PS) } else { - domain = m.MergeLink("/chat/pod/" + m.Option(ice.MSG_USERPOD)) + domain = web.MergeLink(m, "/chat/pod/"+m.Option(ice.MSG_USERPOD)) } } if domain = strings.TrimSuffix(domain, ice.PS); strings.Contains(domain, "/chat/pod/") { domain += web.P(strings.TrimPrefix(m.Prefix(web.P(key)), "web.chat.")) } else { - domain += m.RoutePath(key) + domain += path.Join(strings.TrimPrefix(strings.ReplaceAll(m.Target().Cap(ice.CTX_FOLLOW), ice.PT, ice.PS), "web"), path.Join(key)) } return kit.MergeURL(domain, arg...) } @@ -61,7 +62,7 @@ var Index = &ice.Context{Name: OAUTH, Help: "认证授权", Commands: ice.Comman m.Echo(_merge_url(m, kit.Select(ice.Info.Make.Domain, m.Option(web.DOMAIN)), APPLY, m.OptionSimple(SCOPE), REDIRECT_URI, _merge_url(m, "", REPLY))) }}, APPLY: {Name: "apply scope redirect_uri", Help: "申请", Hand: func(m *ice.Message, arg ...string) { - if m.Right(m.Option(SCOPE)) { + if aaa.Right(m, m.Option(SCOPE)) { token := m.Cmdx(OFFER, mdb.CREATE, aaa.USERNAME, m.Option(ice.MSG_USERNAME), m.OptionSimple(SCOPE, REDIRECT_URI)) m.ProcessReplace(m.Option(REDIRECT_URI), m.OptionSimple(SCOPE), OFFER, _merge_url(m, "", OFFER, ACCESS_TOKEN, token)) } else { @@ -86,7 +87,7 @@ var Index = &ice.Context{Name: OAUTH, Help: "认证授权", Commands: ice.Comman m.RenderStatusBadRequest() // 参数错误 } else { // 申请 - m.RenderCmd(m.Prefix(OAUTH), APPLY) + web.RenderCmd(m, m.Prefix(OAUTH), APPLY) } }}, web.P(REPLY): {Name: "/reply scope offer", Help: "授权", Actions: ctx.CmdAction(), Hand: func(m *ice.Message, arg ...string) { @@ -94,7 +95,7 @@ var Index = &ice.Context{Name: OAUTH, Help: "认证授权", Commands: ice.Comman m.RenderStatusBadRequest() // 参数错误 } else { // 授权 - m.RenderCmd(m.Prefix(OAUTH), REPLY) + web.RenderCmd(m, m.Prefix(OAUTH), REPLY) } }}, web.P(OFFER): {Name: "/offer access_token", Help: "访问", Hand: func(m *ice.Message, arg ...string) { diff --git a/core/chat/pod.go b/core/chat/pod.go index 52638f2c..8e63fc46 100644 --- a/core/chat/pod.go +++ b/core/chat/pod.go @@ -27,19 +27,19 @@ func init() { } if len(arg) == 0 || kit.Select("", arg, 0) == "" { // 节点列表 - m.RenderCmd(web.ROUTE) + web.RenderCmd(m, web.ROUTE) } else if len(arg) == 1 { // 节点首页 if m.Cmd(web.SPACE, arg[0]).Length() == 0 && !strings.Contains(arg[0], ice.PT) { m.Cmd(web.DREAM, cli.START, mdb.NAME, arg[0]) } aaa.UserRoot(m) - if m.RenderWebsite(arg[0], "index.iml", "Header", "", "River", "", "Footer", ""); m.Result() == "" { - m.RenderIndex(web.SERVE, ice.VOLCANOS) + if web.RenderWebsite(m, arg[0], "index.iml", "Header", "", "River", "", "Footer", ""); m.Result() == "" { + web.RenderIndex(m, web.SERVE, ice.VOLCANOS) } } else if arg[1] == WEBSITE { // 节点网页 - m.RenderWebsite(arg[0], path.Join(arg[2:]...)) + web.RenderWebsite(m, arg[0], path.Join(arg[2:]...)) } else if arg[1] == "cmd" { // 节点命令 m.Cmdy(web.SPACE, arg[0], m.Prefix(CMD), path.Join(arg[2:]...)) diff --git a/core/chat/river.go b/core/chat/river.go index 20ad077e..29b6eabd 100644 --- a/core/chat/river.go +++ b/core/chat/river.go @@ -43,8 +43,8 @@ func _river_list(m *ice.Message) { } } - m.Richs(RIVER, nil, mdb.FOREACH, func(key string, value ice.Map) { - m.Richs(RIVER, kit.Keys(mdb.HASH, key, OCEAN), m.Option(ice.MSG_USERNAME), func(k string, val ice.Map) { + mdb.Richs(m, RIVER, nil, mdb.FOREACH, func(key string, value ice.Map) { + mdb.Richs(m, RIVER, kit.Keys(mdb.HASH, key, OCEAN), m.Option(ice.MSG_USERNAME), func(k string, val ice.Map) { m.Push(key, kit.GetMeta(value), []string{mdb.HASH, mdb.NAME}, kit.GetMeta(val)) }) }) @@ -94,7 +94,7 @@ func init() { }) }}, cli.START: {Name: "start name=hi repos template", Help: "创建空间", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(m.Space(m.Option(ice.POD)), web.DREAM, cli.START, arg) + m.Cmdy(web.Space(m, m.Option(ice.POD)), web.DREAM, cli.START, arg) }}, aaa.INVITE: {Name: "invite", Help: "添加设备", Hand: func(m *ice.Message, arg ...string) { m.Cmd(code.PUBLISH, mdb.CREATE, nfs.FILE, ice.BIN_ICE_BIN) @@ -116,7 +116,7 @@ func init() { m.Cmdy(arg[1], arg[2:]) return // 应用列表 } - if !m.Right(RIVER, arg) { + if !aaa.Right(m, RIVER, arg) { m.RenderStatusForbidden() return // 没有授权 } diff --git a/core/chat/search.go b/core/chat/search.go index b3af3c72..12b5a454 100644 --- a/core/chat/search.go +++ b/core/chat/search.go @@ -12,7 +12,7 @@ const SEARCH = "search" func init() { Index.MergeCommands(ice.Commands{ web.P(SEARCH): {Name: "/search", Help: "搜索引擎", Actions: ctx.CmdAction(mdb.SHORT, mdb.NAME), Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(m.Space(m.Option(ice.POD)), mdb.SEARCH, arg).StatusTimeCount() + m.Cmdy(web.Space(m, m.Option(ice.POD)), mdb.SEARCH, arg).StatusTimeCount() }}, }) } diff --git a/core/chat/sso.go b/core/chat/sso.go index f16e444f..d4d8bcc1 100644 --- a/core/chat/sso.go +++ b/core/chat/sso.go @@ -15,7 +15,7 @@ func init() { Index.MergeCommands(ice.Commands{ "/sso": {Name: "/sso", Help: "登录", Hand: func(m *ice.Message, arg ...string) { if m.Option(ice.MSG_USERNAME) == "" { - m.RenderIndex(web.SERVE, ice.VOLCANOS) + web.RenderIndex(m, web.SERVE, ice.VOLCANOS) return } sessid := m.Cmdx(web.SPACE, m.Option(web.SPACE), aaa.SESS, mdb.CREATE, diff --git a/core/chat/storm.go b/core/chat/storm.go index 25212845..3a437117 100644 --- a/core/chat/storm.go +++ b/core/chat/storm.go @@ -4,6 +4,7 @@ import ( ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/ctx" "shylinux.com/x/icebergs/base/mdb" + "shylinux.com/x/icebergs/base/web" kit "shylinux.com/x/toolkits" ) @@ -47,7 +48,6 @@ func init() { } msg := m.Cmd(STORM, m.Option(mdb.HASH), m.Option(mdb.ID)) cmd := kit.Keys(msg.Append(ice.CTX), msg.Append(ice.CMD)) - _action_domain(m, cmd, m.Option(mdb.HASH)) m.Cmdy(cmd, mdb.EXPORT) }}, mdb.IMPORT: {Name: "import", Help: "导入", Hand: func(m *ice.Message, arg ...string) { @@ -56,7 +56,6 @@ func init() { } msg := m.Cmd(STORM, m.Option(mdb.HASH), m.Option(mdb.ID)) cmd := kit.Keys(msg.Append(ice.CTX), msg.Append(ice.CMD)) - _action_domain(m, cmd, m.Option(mdb.HASH)) m.Cmdy(cmd, mdb.IMPORT) }}, SHARE: {Name: "share", Help: "共享", Hand: func(m *ice.Message, arg ...string) { _header_share(m, arg...) }}, @@ -75,14 +74,14 @@ func init() { } if len(arg) > 2 && arg[2] == ice.RUN { // 执行命令 - m.Cmdy(m.Space(kit.Select(m.Option(ice.POD), msg.Append(ice.POD))), kit.Keys(msg.Append(ice.CTX), msg.Append(ice.CMD)), arg[3:]) + m.Cmdy(web.Space(m, kit.Select(m.Option(ice.POD), msg.Append(ice.POD))), kit.Keys(msg.Append(ice.CTX), msg.Append(ice.CMD)), arg[3:]) return } if m.Copy(msg); len(arg) > 1 { // 命令插件 m.ProcessField(arg[0], arg[1], ice.RUN) m.Tables(func(value ice.Maps) { - m.Cmdy(m.Space(value[ice.POD]), ctx.CONTEXT, value[ice.CTX], ctx.COMMAND, value[ice.CMD]) + m.Cmdy(web.Space(m, value[ice.POD]), ctx.CONTEXT, value[ice.CTX], ctx.COMMAND, value[ice.CMD]) }) } else { m.PushAction(mdb.EXPORT, mdb.IMPORT) diff --git a/core/chat/topic.go b/core/chat/topic.go index 9452d180..ffe0b66a 100644 --- a/core/chat/topic.go +++ b/core/chat/topic.go @@ -55,7 +55,7 @@ func init() { m.Cmdy(mdb.INPUTS, m.PrefixKey(), "", mdb.ZONE, arg) }}, "choose": {Name: "choose", Help: "切换", Hand: func(m *ice.Message, arg ...string) { - m.ProcessLocation(m.MergeURL2("", "topic", kit.TrimExt(m.Option(mdb.ZONE), nfs.CSS))) + m.ProcessLocation(web.MergeURL2(m, "", "topic", kit.TrimExt(m.Option(mdb.ZONE), nfs.CSS))) }}, "create": {Name: "create topic=demo hover=gray float=lightgray color=black background=white", Help: "创建", Hand: func(m *ice.Message, arg ...string) { buf, err := kit.Render(` diff --git a/core/chat/trans.go b/core/chat/trans.go index 696732ae..b822f942 100644 --- a/core/chat/trans.go +++ b/core/chat/trans.go @@ -4,6 +4,7 @@ import ( "path" ice "shylinux.com/x/icebergs" + "shylinux.com/x/icebergs/base/aaa" "shylinux.com/x/icebergs/base/ctx" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" @@ -22,17 +23,17 @@ func init() { TRANS: {Name: "trans from to auto", Help: "传输", Actions: ice.MergeAction(ice.Actions{ SEND: {Name: "send", Help: "发送", Hand: func(m *ice.Message, arg ...string) { m.Cmdy(web.SPACE, m.Option(TO), web.SPIDE, ice.DEV, web.SPIDE_SAVE, kit.Select(nfs.PWD, m.Option("to_path")), - m.MergeURL2(path.Join(web.SHARE_LOCAL, m.Option("from_path")), ice.POD, m.Option(FROM), + web.MergeURL2(m, path.Join(web.SHARE_LOCAL, m.Option("from_path")), ice.POD, m.Option(FROM), web.SHARE, m.Cmdx(web.SHARE, mdb.CREATE, mdb.TYPE, web.LOGIN), ), ) - m.Toast(ice.SUCCESS, SEND) + web.Toast(m, ice.SUCCESS, SEND) m.ProcessHold() }}, ice.RUN: {Name: "run", Help: "执行", Hand: func(m *ice.Message, arg ...string) { m.Option(ice.POD, m.Option("_pod")) m.Option(ice.MSG_USERPOD, m.Option("_pod")) - if m.Right(arg) && !m.PodCmd(arg) { + if aaa.Right(m, arg) && !ctx.PodCmd(m, arg) { m.Cmdy(arg) } if arg[0] == nfs.DIR && m.Length() > 0 { @@ -48,7 +49,7 @@ func init() { m.Cmdy(web.ROUTE).RenameAppend(web.ROUTE, TO) return } - m.DisplayLocal("") + ctx.DisplayLocal(m, "") }}, }) } diff --git a/core/chat/website.go b/core/chat/website.go index 0b1e48dc..6dfb6b85 100644 --- a/core/chat/website.go +++ b/core/chat/website.go @@ -16,7 +16,7 @@ import ( ) func _website_url(m *ice.Message, file string) string { - return strings.Split(m.MergeWebsite(file), "?")[0] + return strings.Split(web.MergeWebsite(m, file), "?")[0] } func _website_parse(m *ice.Message, text string, args ...string) (ice.Map, bool) { if text == "" { @@ -55,9 +55,9 @@ func _website_parse(m *ice.Message, text string, args ...string) (ice.Map, bool) data := kit.Dict() switch kit.Ext(ls[0]) { case nfs.JS: - ls[0], data[ctx.DISPLAY] = kit.Select(ctx.CAN_PLUGIN, ice.GetFileCmd(ls[0])), ice.FileURI(ls[0]) + ls[0], data[ctx.DISPLAY] = kit.Select(ctx.CAN_PLUGIN, ctx.GetFileCmd(ls[0])), ctx.FileURI(ls[0]) case nfs.GO: - ls[0] = ice.GetFileCmd(ls[0]) + ls[0] = ctx.GetFileCmd(ls[0]) case nfs.SH: ls[0], data[ctx.ARGS] = "web.code.sh.sh", ls[0] case nfs.SHY: @@ -122,13 +122,13 @@ func _website_render(m *ice.Message, w http.ResponseWriter, r *http.Request, kin msg := m.Spawn(w, r) switch kind { case nfs.ZML: - msg.RenderCmd("can.parse", text, name) + web.RenderCmd(msg, "can.parse", text, name) case nfs.IML: res, _ := _website_parse(msg, text) msg.RenderResult(_website_template2, kit.Format(res)) case nfs.SHY: if r.Method == http.MethodGet { - msg.RenderCmd(msg.Prefix(DIV), text) + web.RenderCmd(msg, msg.Prefix(DIV), text) } else { r.URL.Path = "/chat/cmd/web.chat.div" return false @@ -149,7 +149,7 @@ func _website_render(m *ice.Message, w http.ResponseWriter, r *http.Request, kin } func _website_search(m *ice.Message, kind, name, text string, arg ...string) { m.Cmd(m.PrefixKey(), ice.OptionFields("")).Tables(func(value ice.Maps) { - m.PushSearch(value, mdb.TEXT, m.MergeWebsite(value[nfs.PATH])) + m.PushSearch(value, mdb.TEXT, web.MergeWebsite(m, value[nfs.PATH])) }) } @@ -172,7 +172,7 @@ func init() { if r.Method != http.MethodGet { return false } - if ok := true; m.Richs(WEBSITE, nil, r.URL.Path, func(key string, value ice.Map) { + if ok := true; mdb.Richs(m, WEBSITE, nil, r.URL.Path, func(key string, value ice.Map) { value = kit.GetMeta(value) ok = _website_render(m, w, r, kit.Format(value[mdb.TYPE]), kit.Format(value[mdb.TEXT]), path.Base(r.URL.Path)) }) != nil && ok { @@ -188,7 +188,7 @@ func init() { lex.PARSE: {Hand: func(m *ice.Message, arg ...string) { switch kit.Ext(arg[0]) { case nfs.ZML: - m.RenderCmd("can.parse", m.Cmdx(nfs.CAT, path.Join(SRC_WEBSITE, arg[0]))) + web.RenderCmd(m, "can.parse", m.Cmdx(nfs.CAT, path.Join(SRC_WEBSITE, arg[0]))) case nfs.IML: if res, ok := _website_parse(m, m.Cmdx(nfs.CAT, path.Join(SRC_WEBSITE, arg[0])), arg[1:]...); ok { @@ -213,7 +213,8 @@ func init() { }}, mdb.ENGINE: {Hand: func(m *ice.Message, arg ...string) { if res, ok := _website_parse(m, m.Cmdx(nfs.CAT, path.Join(arg[2], arg[1]))); ok { - m.Echo(kit.Formats(res)).DisplayStoryJSON() + m.Echo(kit.Formats(res)) + ctx.DisplayStoryJSON(m) } else { m.Echo(_website_url(m, strings.TrimPrefix(path.Join(arg[2], arg[1]), SRC_WEBSITE))) } @@ -241,7 +242,7 @@ func init() { }) }}, }, mdb.HashAction(mdb.SHORT, nfs.PATH, mdb.FIELD, "time,path,type,name,text")), Hand: func(m *ice.Message, arg ...string) { - mdb.HashSelect(m, arg...).Tables(func(value ice.Maps) { m.PushAnchor(m.MergeWebsite(value[nfs.PATH])) }) + mdb.HashSelect(m, arg...).Tables(func(value ice.Maps) { m.PushAnchor(web.MergeWebsite(m, value[nfs.PATH])) }) if len(arg) == 0 { // 文件列表 m.Cmd(nfs.DIR, SRC_WEBSITE, func(f os.FileInfo, p string) { m.Push("", kit.Dict( @@ -249,17 +250,17 @@ func init() { nfs.PATH, ice.PS+strings.TrimPrefix(p, SRC_WEBSITE), mdb.TYPE, kit.Ext(p), mdb.NAME, path.Base(p), mdb.TEXT, m.Cmdx(nfs.CAT, p), ), kit.Split(m.Config(mdb.FIELD))).PushButton("") - m.PushAnchor(m.MergeLink(path.Join(CHAT_WEBSITE, strings.TrimPrefix(p, SRC_WEBSITE)))) + m.PushAnchor(web.MergeURL2(m, path.Join(CHAT_WEBSITE, strings.TrimPrefix(p, SRC_WEBSITE)))) }).Sort(nfs.PATH) } if m.Length() == 0 && len(arg) > 0 { // 文件详情 m.Push(mdb.TEXT, m.Cmdx(nfs.CAT, path.Join(SRC_WEBSITE, path.Join(arg...)))) m.Push(nfs.PATH, path.Join(CHAT_WEBSITE, path.Join(arg...))) - m.PushAnchor(m.MergeLink(m.Append(nfs.PATH))) + m.PushAnchor(web.MergeLink(m, m.Append(nfs.PATH))) } if len(arg) > 0 { // 文件预览 - m.PushQRCode(mdb.SCAN, m.MergeURL2(m.Append(nfs.PATH))) + m.PushQRCode(mdb.SCAN, web.MergeURL2(m, m.Append(nfs.PATH))) m.EchoIFrame(m.Append(nfs.PATH)) } }}, diff --git a/core/code/autogen.go b/core/code/autogen.go index 7377a0b0..7ea67d16 100644 --- a/core/code/autogen.go +++ b/core/code/autogen.go @@ -187,7 +187,7 @@ func init() { _defs(m, mdb.KEY, kit.Keys("web.code", m.Option(mdb.ZONE), m.Option(mdb.NAME))) m.Option(mdb.TEXT, kit.Format("`name:\"%s\" help:\"%s\"`", _defs_list(m), m.Option(mdb.HELP))) - m.OptionFiles(nfs.DiskFile) + nfs.OptionFiles(m, nfs.DiskFile) if p := path.Join(ice.SRC, m.Option(mdb.ZONE), kit.Keys(m.Option(mdb.NAME), GO)); !kit.FileExists(p) { _autogen_module(m, p) _autogen_import(m, path.Join(ice.SRC, m.Option(cli.MAIN)), m.Option(mdb.ZONE), _autogen_mod(m, ice.GO_MOD)) diff --git a/core/code/binpack.go b/core/code/binpack.go index f500ce6c..5406c43b 100644 --- a/core/code/binpack.go +++ b/core/code/binpack.go @@ -132,26 +132,7 @@ func init() { mdb.INSERT: {Name: "insert", Help: "添加", Hand: func(m *ice.Message, arg ...string) { m.Cmd(mdb.INSERT, m.PrefixKey(), "", mdb.HASH, nfs.PATH, arg[0]) }}, - mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) { - ice.Info.Pack = map[string][]byte{} - }}, - mdb.EXPORT: {Name: "export", Help: "导出", Hand: func(m *ice.Message, arg ...string) { - for key, value := range ice.Info.Pack { - if strings.HasPrefix(key, ice.PS) { - key = ice.USR_VOLCANOS + key - } - m.Log_EXPORT(nfs.FILE, kit.WriteFile(key, value), nfs.SIZE, len(value)) - } - }}, }, mdb.HashAction(mdb.SHORT, nfs.PATH)), Hand: func(m *ice.Message, arg ...string) { - if len(arg) == 0 { - for k, v := range ice.Info.Pack { - m.Push(nfs.PATH, k).Push(nfs.SIZE, len(v)) - } - m.Sort(nfs.PATH) - return - } - m.Echo(string(ice.Info.Pack[arg[0]])) }}, }) } diff --git a/core/code/compile.go b/core/code/compile.go index 618e5739..d65b3b3f 100644 --- a/core/code/compile.go +++ b/core/code/compile.go @@ -8,6 +8,7 @@ import ( "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" "shylinux.com/x/icebergs/base/tcp" + "shylinux.com/x/icebergs/base/web" kit "shylinux.com/x/toolkits" ) @@ -52,12 +53,12 @@ func init() { }}, INSTALL: {Name: "compile", Help: "安装", Hand: func(m *ice.Message, arg ...string) { if cli.IsAlpine(m) { - cli.PushStream(m) + web.PushStream(m) m.Cmd(cli.SYSTEM, "apk", "add", GIT, GO) return } if m.Cmdx(cli.SYSTEM, nfs.FIND, GIT) == "" { - m.Toast("please install git") + web.Toast(m, "please install git") m.Echo(ice.FALSE) return } @@ -74,7 +75,7 @@ func init() { m.Cmd(cli.SYSTEM, GO, "get", "shylinux.com/x/ice") // 执行编译 - cli.PushStream(m) + web.PushStream(m) main, file, goos, arch := _compile_target(m, arg...) m.Optionv(cli.CMD_ENV, kit.Simple(m.Configv(cli.ENV), cli.HOME, kit.Env(cli.HOME), cli.PATH, kit.Env(cli.PATH), cli.GOOS, goos, cli.GOARCH, arch)) if msg := m.Cmd(cli.SYSTEM, GO, cli.BUILD, "-o", file, main, ice.SRC_VERSION_GO, ice.SRC_BINPACK_GO); !cli.IsSuccess(msg) { @@ -84,7 +85,7 @@ func init() { m.Option(cli.CMD_OUTPUT, "") // 编译成功 - m.Log_EXPORT(nfs.SOURCE, main, nfs.TARGET, file) + m.Logs(mdb.EXPORT, nfs.SOURCE, main, nfs.TARGET, file) m.Cmdy(nfs.DIR, file, nfs.DIR_WEB_FIELDS) m.Cmdy(PUBLISH, ice.CONTEXTS) m.StatusTimeCount() diff --git a/core/code/favor.go b/core/code/favor.go index b7962225..55895e8c 100644 --- a/core/code/favor.go +++ b/core/code/favor.go @@ -2,6 +2,7 @@ package code import ( ice "shylinux.com/x/icebergs" + "shylinux.com/x/icebergs/base/ctx" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" kit "shylinux.com/x/toolkits" @@ -14,7 +15,7 @@ func init() { FAVOR: {Name: "favor zone id auto insert test page", Help: "收藏夹", Actions: ice.MergeAction(ice.Actions{ mdb.INSERT: {Name: "insert zone=数据结构 type=go name=hi text=hello path file line", Help: "添加"}, INNER: {Name: "inner", Help: "源码", Hand: func(m *ice.Message, arg ...string) { - m.ProcessCommand(INNER, m.OptionSplit("path,file,line"), arg...) + ctx.ProcessCommand(m, INNER, m.OptionSplit("path,file,line"), arg...) }}, "test": {Name: "test zone=hi count=10", Help: "测试", Hand: func(m *ice.Message, arg ...string) { m.Cmd(mdb.INSERT, m.PrefixKey(), "", mdb.HASH, m.OptionSimple(mdb.ZONE)) diff --git a/core/code/go.go b/core/code/go.go index c42a6fb1..1187816c 100644 --- a/core/code/go.go +++ b/core/code/go.go @@ -10,6 +10,7 @@ import ( ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/cli" + "shylinux.com/x/icebergs/base/ctx" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" kit "shylinux.com/x/toolkits" @@ -59,7 +60,7 @@ func _go_grep(m *ice.Message, key string, dir string) { m.Cmd(nfs.GREP, dir, key).Tables(func(value ice.Maps) { m.PushSearch(value) }) } -var _cache_mods = map[string]*ice.Message{} +var _cache_mods = ice.Messages{} var _cache_lock = sync.Mutex{} func _go_doc(m *ice.Message, mod string, pkg string) *ice.Message { @@ -83,7 +84,7 @@ func _go_doc(m *ice.Message, mod string, pkg string) *ice.Message { func _go_exec(m *ice.Message, arg ...string) { if m.Option("some") == "run" { - args := []string{"./bin/ice.bin", ice.GetFileCmd(path.Join(arg[2], arg[1]))} + args := []string{"./bin/ice.bin", ctx.GetFileCmd(path.Join(arg[2], arg[1]))} m.Cmdy(cli.SYSTEM, args) m.StatusTime("args", kit.Join(args, " ")) m.Debug(m.FormatsMeta()) @@ -160,10 +161,10 @@ func _go_show(m *ice.Message, arg ...string) { } }) } else { - if key := ice.GetFileCmd(path.Join(arg[2], arg[1])); key != "" { - m.ProcessCommand(key, kit.Simple()) + if key := ctx.GetFileCmd(path.Join(arg[2], arg[1])); key != "" { + ctx.ProcessCommand(m, key, kit.Simple()) } else { - m.ProcessCommand("web.wiki.word", kit.Simple(strings.ReplaceAll(path.Join(arg[2], arg[1]), ".go", ".shy"))) + ctx.ProcessCommand(m, "web.wiki.word", kit.Simple(strings.ReplaceAll(path.Join(arg[2], arg[1]), ".go", ".shy"))) } } } diff --git a/core/code/inner.go b/core/code/inner.go index 6120c204..b2755806 100644 --- a/core/code/inner.go +++ b/core/code/inner.go @@ -5,6 +5,7 @@ import ( "strings" ice "shylinux.com/x/icebergs" + "shylinux.com/x/icebergs/base/aaa" "shylinux.com/x/icebergs/base/cli" "shylinux.com/x/icebergs/base/ctx" "shylinux.com/x/icebergs/base/mdb" @@ -14,7 +15,7 @@ import ( ) func _inner_list(m *ice.Message, ext, file, dir string, arg ...string) { - if !m.Right(dir, file) { + if !aaa.Right(m, dir, file) { return // 没有权限 } if m.Conf(nfs.CAT, kit.Keym(ssh.SOURCE, ext)) == ice.TRUE { @@ -24,13 +25,13 @@ func _inner_list(m *ice.Message, ext, file, dir string, arg ...string) { } } func _inner_show(m *ice.Message, ext, file, dir string, arg ...string) { - if !m.Right(dir, file) { + if !aaa.Right(m, dir, file) { return // 没有权限 } m.Cmdy(mdb.RENDER, ext, file, dir, arg) } func _inner_exec(m *ice.Message, ext, file, dir string, arg ...string) { - if !m.Right(dir, file) { + if !aaa.Right(m, dir, file) { return // 没有权限 } // defer m.StatusTime() diff --git a/core/code/install.go b/core/code/install.go index d6ae82d1..e0e0399a 100644 --- a/core/code/install.go +++ b/core/code/install.go @@ -39,12 +39,12 @@ func _install_download(m *ice.Message) { // 创建文件 m.Cmd(nfs.SAVE, file, "") - m.GoToast(web.DOWNLOAD, func(toast func(string, int, int)) { + web.GoToast(m, web.DOWNLOAD, func(toast func(string, int, int)) { m.Cmd(mdb.INSERT, INSTALL, "", mdb.HASH, mdb.NAME, name, nfs.PATH, file, mdb.LINK, link) - defer m.ToastSuccess() + defer web.ToastSuccess(m) // 下载进度 - m.Richs(INSTALL, "", name, func(key string, value ice.Map) { + mdb.Richs(m, INSTALL, "", name, func(key string, value ice.Map) { value = kit.GetMeta(value) m.OptionCB(web.SPIDE, func(count int, total int, step int) { value[mdb.COUNT], value[mdb.TOTAL], value[mdb.VALUE] = count, total, step @@ -62,7 +62,7 @@ func _install_build(m *ice.Message, arg ...string) string { pp := kit.Path(path.Join(p, "_install")) // 推流 - cli.PushStream(m) + web.PushStream(m) defer m.ProcessHold() // 配置 @@ -168,10 +168,10 @@ func init() { }}, cli.BUILD: {Name: "build link", Help: "构建", Hand: func(m *ice.Message, arg ...string) { if err := _install_build(m, arg...); err != "" { - m.ToastFailure(cli.BUILD) + web.ToastFailure(m, cli.BUILD) m.Echo(err) } else { - m.ToastSuccess(cli.BUILD) + web.ToastSuccess(m, cli.BUILD) } }}, cli.ORDER: {Name: "order link path", Help: "加载", Hand: func(m *ice.Message, arg ...string) { @@ -224,7 +224,7 @@ func InstallSoftware(m *ice.Message, bin string, list ice.Any) (ok bool) { } kit.Fetch(list, func(index int, value ice.Map) { if strings.Contains(m.Cmdx(cli.RUNTIME, kit.Keys(tcp.HOST, cli.OSID)), kit.Format(value[cli.OSID])) { - cli.PushStream(m) + web.PushStream(m) m.Cmd(cli.SYSTEM, value[ice.CMD]) ok = true } diff --git a/core/code/js.go b/core/code/js.go index 179c505c..25ef5dd7 100644 --- a/core/code/js.go +++ b/core/code/js.go @@ -1,11 +1,13 @@ package code import ( + "os" "path" "strings" ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/cli" + "shylinux.com/x/icebergs/base/ctx" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" "shylinux.com/x/icebergs/base/web" @@ -13,18 +15,23 @@ import ( ) func _js_main_script(m *ice.Message, arg ...string) (res []string) { - if res = append(res, kit.Format(`global.plugin = "%s"`, kit.Path(arg[2], arg[1]))); len(ice.Info.Pack) == 0 { + res = append(res, kit.Format(`global.plugin = "%s"`, kit.Path(arg[2], arg[1]))) + if _, e := nfs.DiskFile.StatFile("usr/volcanos/proto.js"); e == nil { res = append(res, kit.Format(`require("%s")`, kit.Path("usr/volcanos/proto.js"))) res = append(res, kit.Format(`require("%s")`, kit.Path("usr/volcanos/publish/client/nodejs/proto.js"))) } else { for _, file := range []string{"proto.js", "frame.js", "lib/base.js", "lib/core.js", "lib/misc.js", "lib/page.js", "publish/client/nodejs/proto.js"} { res = append(res, `_can_name = "`+kit.Path(ice.USR_VOLCANOS, file)+`"`) - res = append(res, string(ice.Info.Pack[ice.PS+file])) + if b, e := nfs.ReadFile(m, path.Join(ice.USR_VOLCANOS, file)); e == nil { + res = append(res, string(b)) + } } } - if b, ok := ice.Info.Pack[path.Join(arg[2], arg[1])]; ok && !kit.FileExists(kit.Path(arg[2], arg[1])) { + if _, e := nfs.DiskFile.StatFile(path.Join(arg[2], arg[1])); os.IsNotExist(e) { res = append(res, `_can_name = "`+kit.Path(arg[2], arg[1])+`"`) - res = append(res, string(b)) + if b, e := nfs.ReadFile(m, path.Join(arg[2], arg[1])); e == nil { + res = append(res, string(b)) + } } return } @@ -70,7 +77,7 @@ func init() { LoadPlug(m, JS) }}, mdb.RENDER: {Hand: func(m *ice.Message, arg ...string) { - key := ice.GetFileCmd(kit.Replace(path.Join(arg[2], arg[1]), ".js", ".go")) + key := ctx.GetFileCmd(kit.Replace(path.Join(arg[2], arg[1]), ".js", ".go")) if key == "" { for p, k := range ice.Info.File { if strings.HasPrefix(p, path.Dir(path.Join(arg[2], arg[1]))) { @@ -79,7 +86,7 @@ func init() { } } m.Display(path.Join("/require", path.Join(arg[2], arg[1]))) - m.ProcessCommand(kit.Select("can.code.inner._plugin", key), kit.Simple()) + ctx.ProcessCommand(m, kit.Select("can.code.inner._plugin", key), kit.Simple()) }}, mdb.ENGINE: {Hand: func(m *ice.Message, arg ...string) { _js_exec(m, arg...) diff --git a/core/code/oauth.go b/core/code/oauth.go index 77d06c0b..6682378a 100644 --- a/core/code/oauth.go +++ b/core/code/oauth.go @@ -25,7 +25,9 @@ func init() { Index.MergeCommands(ice.Commands{ OAUTH: {Name: "oauth hash auto", Help: "授权", Actions: ice.MergeAction(ice.Actions{ ctx.CONFIG: {Name: "config client_id client_secret redirect_uri", Help: "配置", Hand: func(m *ice.Message, arg ...string) { - m.ConfigOption(CLIENT_ID, CLIENT_SECRET, REDIRECT_URI) + for _, k := range []string{CLIENT_ID, CLIENT_SECRET, REDIRECT_URI} { + m.Config(k, kit.Select(m.Config(k), m.Option(k))) + } }}, mdb.INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) { if arg[0] == mdb.HASH { @@ -77,7 +79,7 @@ func init() { }}, "/oauth": {Name: "/oauth", Help: "授权", Actions: ice.MergeAction(ice.Actions{}, ctx.CmdAction()), Hand: func(m *ice.Message, arg ...string) { if m.Option(CODE) != "" { - m.RenderCmd(m.PrefixKey(), m.Cmdx(m.PrefixKey(), mdb.CREATE, m.OptionSimple(CODE))) + web.RenderCmd(m, m.PrefixKey(), m.Cmdx(m.PrefixKey(), mdb.CREATE, m.OptionSimple(CODE))) } }}, }) diff --git a/core/code/pprof.go b/core/code/pprof.go index dfd95caf..081c2ae7 100644 --- a/core/code/pprof.go +++ b/core/code/pprof.go @@ -64,7 +64,7 @@ func init() { }, mdb.ZoneAction(mdb.SHORT, mdb.ZONE, mdb.FIELD, "time,id,text,file", PPROF, kit.List(GO, "tool", PPROF))), Hand: func(m *ice.Message, arg ...string) { m.Fields(len(arg), "time,zone,count,binnary,service,seconds", m.Config(mdb.FIELD)) if mdb.ZoneSelect(m, arg...); len(arg) == 0 { - m.EchoAnchor(m.MergeLink("/code/pprof/")) + m.EchoAnchor(web.MergeLink(m, "/code/pprof/")) m.PushAction(ice.RUN, mdb.REMOVE) m.Action(mdb.CREATE) return diff --git a/core/code/publish.go b/core/code/publish.go index b881ca82..245573b9 100644 --- a/core/code/publish.go +++ b/core/code/publish.go @@ -10,6 +10,7 @@ import ( ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/aaa" "shylinux.com/x/icebergs/base/cli" + "shylinux.com/x/icebergs/base/gdb" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" "shylinux.com/x/icebergs/base/tcp" @@ -29,7 +30,7 @@ func _publish_file(m *ice.Message, file string, arg ...string) string { // 发布文件 target := path.Join(m.Config(nfs.PATH), kit.Select(path.Base(file), arg, 0)) - m.Log_EXPORT(PUBLISH, target, cli.FROM, file) + m.Logs(mdb.EXPORT, PUBLISH, target, cli.FROM, file) m.Cmd(nfs.LINK, target, file) return target } @@ -68,7 +69,7 @@ func init() { m.Cmd(aaa.ROLE, aaa.WHITE, aaa.VOID, m.Config(nfs.PATH)) m.Cmd(aaa.ROLE, aaa.WHITE, aaa.VOID, m.PrefixKey()) m.Config(ice.CONTEXTS, _contexts) - m.Watch(web.SERVE_START, m.PrefixKey()) + gdb.Watch(m, web.SERVE_START, m.PrefixKey()) }}, web.SERVE_START: {Name: "serve.start", Help: "服务启动", Hand: func(m *ice.Message, arg ...string) { _publish_file(m, ice.ICE_BIN) @@ -110,7 +111,7 @@ func init() { case ice.CORE: if !kit.FileExists(".git") { - repos := m.MergeURL2("/x/" + m.Option(ice.MSG_USERPOD)) + repos := web.MergeURL2(m, "/x/"+m.Option(ice.MSG_USERPOD)) m.Cmd(cli.SYSTEM, "git", "init") m.Cmd(cli.SYSTEM, "git", "remote", "add", "origin", repos) m.Cmd("web.code.git.repos", mdb.CREATE, repos, "master", "", nfs.PWD) @@ -148,10 +149,10 @@ func init() { list = append(list, text) }) - cli.PushStream(m) + web.PushStream(m) defer m.ProcessHold() - defer m.ToastSuccess() defer m.StatusTimeCount() + defer web.ToastSuccess(m) m.Cmd(nfs.TAR, kit.Path(ice.USR_PUBLISH, "contexts.bin.tar.gz"), list) m.Cmd(nfs.TAR, kit.Path(ice.USR_PUBLISH, "contexts.src.tar.gz"), ice.MAKEFILE, ice.ETC_MISS_SH, ice.SRC_MAIN_GO, ice.GO_MOD, ice.GO_SUM) m.Cmd(nfs.TAR, kit.Path(ice.USR_PUBLISH, "contexts.home.tar.gz"), ".vim/plugged", kit.Dict(nfs.DIR_ROOT, kit.Env(cli.HOME))) diff --git a/core/code/py.go b/core/code/py.go index 724d4462..eb3aeda6 100644 --- a/core/code/py.go +++ b/core/code/py.go @@ -12,9 +12,11 @@ import ( func _py_main_script(m *ice.Message, arg ...string) { const PYTHON2 = "python2" - if kit.FileExists(kit.Path(arg[2], arg[1])) { - m.Cmdy(cli.SYSTEM, PYTHON2, kit.Path(arg[2], arg[1])) - } else if b, ok := ice.Info.Pack[path.Join(arg[2], arg[1])]; ok && len(b) > 0 { + + if _, e := nfs.DiskFile.StatFile(path.Join(arg[2], arg[1])); e == nil { + m.Cmdy(cli.SYSTEM, PYTHON2, path.Join(arg[2], arg[1])) + + } else if b, e := nfs.ReadFile(m, path.Join(arg[2], arg[1])); e == nil { m.Cmdy(cli.SYSTEM, PYTHON2, "-c", string(b)) } if m.StatusTime(); cli.IsSuccess(m) { diff --git a/core/code/sh.go b/core/code/sh.go index e56910bd..cc1986e0 100644 --- a/core/code/sh.go +++ b/core/code/sh.go @@ -5,13 +5,14 @@ import ( ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/cli" + "shylinux.com/x/icebergs/base/ctx" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" kit "shylinux.com/x/toolkits" ) func _sh_main_script(m *ice.Message, arg ...string) (res []string) { - if cmd := ice.GetFileCmd(path.Join(arg[2], arg[1])); cmd != "" { + if cmd := ctx.GetFileCmd(path.Join(arg[2], arg[1])); cmd != "" { res = append(res, kit.Format(`#! /bin/sh export ctx_dev=%s; ctx_pod=%s ctx_temp=$(mktemp); curl -fsSL $ctx_dev -o $ctx_temp; source $ctx_temp &>/dev/null _done="" @@ -29,9 +30,9 @@ _action() { `, "http://localhost:9020", m.Option(ice.MSG_USERPOD), cmd)) } - if kit.FileExists(kit.Path(arg[2], arg[1])) { + if _, e := nfs.DiskFile.StatFile(path.Join(arg[2], arg[1])); e == nil { res = append(res, kit.Format("source %s", kit.Path(arg[2], arg[1]))) - } else if b, ok := ice.Info.Pack[path.Join(arg[2], arg[1])]; ok && len(b) > 0 { + } else if b, e := nfs.ReadFile(m, path.Join(arg[2], arg[1])); e == nil { res = append(res, string(b)) } m.Cmdy(cli.SYSTEM, SH, "-c", kit.Join(res, ice.NL)) diff --git a/core/code/shy.go b/core/code/shy.go index 3b51b0cd..cbfb4024 100644 --- a/core/code/shy.go +++ b/core/code/shy.go @@ -43,7 +43,7 @@ func init() { LoadPlug(m, SHY) }}, mdb.RENDER: {Hand: func(m *ice.Message, arg ...string) { - m.ProcessCommand("web.wiki.word", kit.Simple(path.Join(arg[2], arg[1]))) + ctx.ProcessCommand(m, "web.wiki.word", kit.Simple(path.Join(arg[2], arg[1]))) }}, mdb.ENGINE: {Hand: func(m *ice.Message, arg ...string) { _shy_exec(m, arg...) diff --git a/core/code/upgrade.go b/core/code/upgrade.go index 79cf8989..df296d68 100644 --- a/core/code/upgrade.go +++ b/core/code/upgrade.go @@ -28,7 +28,7 @@ func init() { m.Sleep("1s").Go(func() { m.Cmd(ice.EXIT, 1) }) }}, }, Hand: func(m *ice.Message, arg ...string) { - m.Grows(m.CommandKey(), kit.Keys(mdb.HASH, kit.Select(cli.SYSTEM, arg, 0)), "", "", func(index int, value ice.Map) { + mdb.Grows(m, m.CommandKey(), kit.Keys(mdb.HASH, kit.Select(cli.SYSTEM, arg, 0)), "", "", func(index int, value ice.Map) { if value[nfs.FILE] == ice.ICE_BIN { // 程序文件 value[nfs.FILE] = kit.Keys(ice.ICE, runtime.GOOS, runtime.GOARCH) defer m.Cmd(cli.SYSTEM, "mv", value[nfs.FILE], ice.BIN_ICE_BIN) @@ -45,9 +45,9 @@ func init() { m.Cmd(nfs.TAR, mdb.EXPORT, dir, "-C", path.Dir(dir)) } }) - if m.ToastSuccess(); m.Option(ice.EXIT) == ice.TRUE { + if web.ToastSuccess(m); m.Option(ice.EXIT) == ice.TRUE { m.Sleep("1s").Go(func() { m.Cmd(ice.EXIT, 1) }) - m.ToastRestart() + web.ToastRestart(m) } }}, }}) diff --git a/core/code/vimer.go b/core/code/vimer.go index 5f0c12b8..0c642739 100644 --- a/core/code/vimer.go +++ b/core/code/vimer.go @@ -79,7 +79,7 @@ func _vimer_inputs(m *ice.Message, arg ...string) { m.Push(nfs.FILE, strings.ReplaceAll(file, ice.PT+ext, ice.PT+t)) } } - case nfs.WEBSITE: + case web.WEBSITE: switch arg[0] { case nfs.FILE: name := kit.TrimExt(kit.Select("hi.zml", arg, 1), "") @@ -181,9 +181,9 @@ func init() { m.Option(mdb.TEXT, strings.TrimSpace(kit.Select(_vimer_defs(m, kit.Ext(m.Option(nfs.FILE))), m.Option(mdb.TEXT)))) m.Cmdy(TEMPLATE, nfs.DEFS) }}, - nfs.WEBSITE: {Name: "website file=hi.zml", Help: "网页", Hand: func(m *ice.Message, arg ...string) { + web.WEBSITE: {Name: "website file=hi.zml", Help: "网页", Hand: func(m *ice.Message, arg ...string) { m.Option(mdb.TEXT, strings.TrimSpace(kit.Select(_vimer_defs(m, kit.Ext(m.Option(nfs.FILE))), m.Option(mdb.TEXT)))) - m.Option(nfs.FILE, path.Join(nfs.WEBSITE, m.Option(nfs.FILE))) + m.Option(nfs.FILE, path.Join(web.WEBSITE, m.Option(nfs.FILE))) m.Cmdy(TEMPLATE, nfs.DEFS) }}, web.DREAM: {Name: "dream name=hi repos", Help: "空间", Hand: func(m *ice.Message, arg ...string) { @@ -195,7 +195,7 @@ func init() { mdb.SEARCH: {Name: "search type name text", Help: "搜索", Hand: func(m *ice.Message, arg ...string) { if arg[0] == mdb.FOREACH && arg[1] == "" { - m.PushSearch(mdb.TYPE, "go", mdb.NAME, "src/main.go", mdb.TEXT, m.MergeCmd("")) + m.PushSearch(mdb.TYPE, "go", mdb.NAME, "src/main.go", mdb.TEXT, web.MergeCmd(m, "")) } }}, mdb.INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) { @@ -217,13 +217,13 @@ func init() { m.Cmdy(nfs.CAT, ice.GO_MOD) m.Cmdy(WEBPACK, mdb.REMOVE) m.ProcessInner() - m.ToastSuccess() + web.ToastSuccess(m) }}, BINPACK: {Name: "binpack", Help: "打包模式", Hand: func(m *ice.Message, arg ...string) { m.Cmdy(WEBPACK, mdb.CREATE) m.Cmdy(AUTOGEN, BINPACK) m.ProcessInner() - m.ToastSuccess() + web.ToastSuccess(m) }}, }, Hand: func(m *ice.Message, arg ...string) { m.Cmdy(INNER, arg) diff --git a/core/code/webpack.go b/core/code/webpack.go index 6f68d3ce..a12a6410 100644 --- a/core/code/webpack.go +++ b/core/code/webpack.go @@ -2,6 +2,7 @@ package code import ( "fmt" + "os" "path" "strings" @@ -26,7 +27,7 @@ func _webpack_can(m *ice.Message) { m.Cmdy(nfs.DIR, _volcanos(m, PAGE)) } func _webpack_cache(m *ice.Message, dir string, write bool) { - if len(ice.Info.Pack) > 0 { + if _, e := nfs.DiskFile.StatFile(ice.USR_VOLCANOS); os.IsNotExist(e) { return } diff --git a/core/code/xterm.go b/core/code/xterm.go index 050b02bc..477b737b 100644 --- a/core/code/xterm.go +++ b/core/code/xterm.go @@ -13,11 +13,12 @@ import ( "shylinux.com/x/icebergs/base/cli" "shylinux.com/x/icebergs/base/ctx" "shylinux.com/x/icebergs/base/mdb" + "shylinux.com/x/icebergs/base/web" kit "shylinux.com/x/toolkits" ) func _xterm_socket(m *ice.Message, h, t string) { - defer m.RLock()() + defer mdb.RLock(m)() m.Option(ice.MSG_DAEMON, m.Conf("", kit.Keys(mdb.HASH, h, mdb.META, mdb.TEXT))) m.Option(mdb.TEXT, t) } @@ -40,12 +41,12 @@ func _xterm_get(m *ice.Message, h string, must bool) (f *os.File) { for { if n, e := tty.Read(buf); !m.Warn(e) { _xterm_socket(m, h, base64.StdEncoding.EncodeToString(buf[:n])) - m.PushNoticeGrow("data") + web.PushNoticeGrow(m, "data") } else { break } } - m.PushNoticeGrow("exit") + web.PushNoticeGrow(m, "exit") }) return tty }).(*os.File) @@ -116,7 +117,8 @@ func init() { } }}, }, mdb.HashAction(mdb.FIELD, "time,hash,type,name,text,extra"), ctx.CmdAction()), Hand: func(m *ice.Message, arg ...string) { - mdb.HashSelect(m, kit.Slice(arg, 0, 1)...).DisplayLocal("") + mdb.HashSelect(m, kit.Slice(arg, 0, 1)...) + ctx.DisplayLocal(m, "") }}, }) } diff --git a/core/code/zml.go b/core/code/zml.go index 5bb1d833..31f6c588 100644 --- a/core/code/zml.go +++ b/core/code/zml.go @@ -7,10 +7,11 @@ import ( ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" + "shylinux.com/x/icebergs/base/web" ) func _website_url(m *ice.Message, file string) string { - return strings.Split(m.MergeWebsite(file), "?")[0] + return strings.Split(web.MergeWebsite(m, file), "?")[0] } const ZML = nfs.ZML diff --git a/core/mall/asset.go b/core/mall/asset.go index 7070a95b..e0046439 100644 --- a/core/mall/asset.go +++ b/core/mall/asset.go @@ -4,6 +4,7 @@ import ( ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/ctx" "shylinux.com/x/icebergs/base/mdb" + "shylinux.com/x/icebergs/base/web" kit "shylinux.com/x/toolkits" ) @@ -89,7 +90,7 @@ func init() { } else { _asset_check(m, m.Option(ACCOUNT)) } - m.Toast("核算成功") + web.Toast(m, "核算成功") }}, }, mdb.ZoneAction(), ctx.CmdAction()), Hand: func(m *ice.Message, arg ...string) { m.Fields(len(arg), "time,account,amount,count", m.Config(mdb.FIELD)) diff --git a/core/team/epic.go b/core/team/epic.go index 85d7d527..b463c6e5 100644 --- a/core/team/epic.go +++ b/core/team/epic.go @@ -4,6 +4,7 @@ import ( "time" ice "shylinux.com/x/icebergs" + "shylinux.com/x/icebergs/base/ctx" "shylinux.com/x/icebergs/base/mdb" kit "shylinux.com/x/toolkits" ) @@ -27,7 +28,8 @@ func init() { )) } }) - m.Sort(mdb.TIME).PushAction(mdb.MODIFY, mdb.REMOVE).DisplayTableCard() + m.Sort(mdb.TIME).PushAction(mdb.MODIFY, mdb.REMOVE) + ctx.DisplayTableCard(m) }}, }) } diff --git a/core/team/plan.go b/core/team/plan.go index ddd4cc24..57cb698b 100644 --- a/core/team/plan.go +++ b/core/team/plan.go @@ -4,7 +4,9 @@ import ( "time" ice "shylinux.com/x/icebergs" + "shylinux.com/x/icebergs/base/ctx" "shylinux.com/x/icebergs/base/mdb" + "shylinux.com/x/icebergs/base/web" kit "shylinux.com/x/toolkits" ) @@ -40,7 +42,7 @@ func _plan_scope(m *ice.Message, tz int, arg ...string) (time.Time, time.Time) { return begin_time, end_time } func _plan_list(m *ice.Message, begin_time, end_time time.Time) *ice.Message { - m.Option(ice.CACHE_LIMIT, "100") + m.Option(mdb.CACHE_LIMIT, "100") m.Fields(0, "begin_time,close_time,zone,id,level,status,score,type,name,text,pod,extra") m.OptionCB(mdb.SELECT, func(key string, fields []string, value, val ice.Map) { begin, _ := time.ParseInLocation(ice.MOD_TIME, kit.Format(value[BEGIN_TIME]), time.Local) @@ -77,13 +79,13 @@ func init() { }}, mdb.SEARCH: {Name: "search", Help: "搜索", Hand: func(m *ice.Message, arg ...string) { if arg[0] == mdb.FOREACH && arg[1] == "" { - m.PushSearch(mdb.TYPE, "plan", mdb.NAME, "", mdb.TEXT, m.MergeCmd("")) + m.PushSearch(mdb.TYPE, "plan", mdb.NAME, "", mdb.TEXT, web.MergeCmd(m, "")) } }}, ice.RUN: {Name: "run", Help: "执行", Hand: func(m *ice.Message, arg ...string) { m.Option(ice.POD, m.Option("task.pod")) m.Option("task.pod", "") - if m.PodCmd(m.PrefixKey(), ice.RUN, arg) { + if ctx.PodCmd(m, m.PrefixKey(), ice.RUN, arg) { return } msg := m.Cmd(TASK, arg[0], arg[1]) @@ -93,7 +95,7 @@ func init() { arg = kit.Slice(arg, 0, 2) begin_time, end_time := _plan_scope(m, 8, arg...) _plan_list(m, begin_time, end_time) - m.PushPodCmd(m.CommandKey(), arg...) + web.PushPodCmd(m, m.CommandKey(), arg...) }}, }) } diff --git a/core/team/todo.go b/core/team/todo.go index 1cca15e1..8b82a069 100644 --- a/core/team/todo.go +++ b/core/team/todo.go @@ -4,6 +4,7 @@ import ( ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/cli" "shylinux.com/x/icebergs/base/mdb" + "shylinux.com/x/icebergs/base/web" ) const TODO = "todo" @@ -23,7 +24,7 @@ func init() { }, mdb.HashAction(mdb.FIELD, "time,hash,zone,name,text")), Hand: func(m *ice.Message, arg ...string) { m.Display("/plugin/table.js", "style", "card") mdb.HashSelect(m, arg...).PushAction(cli.START, mdb.REMOVE) - m.PushPodCmd(m.CommandKey(), arg...) + web.PushPodCmd(m, m.CommandKey(), arg...) }}, }) } diff --git a/core/wiki/chart.go b/core/wiki/chart.go index f1ede840..03ae98dc 100644 --- a/core/wiki/chart.go +++ b/core/wiki/chart.go @@ -42,11 +42,11 @@ func (item *Item) Dump(m *ice.Message) *ice.Message { } type Group struct { - list map[string]*ice.Message + list ice.Messages } func NewGroup(m *ice.Message, arg ...string) *Group { - g := &Group{list: map[string]*ice.Message{}} + g := &Group{list: ice.Messages{}} for _, k := range arg { g.list[k] = m.Spawn() } diff --git a/core/wiki/data.go b/core/wiki/data.go index f9777cf2..bde32152 100644 --- a/core/wiki/data.go +++ b/core/wiki/data.go @@ -1,6 +1,9 @@ package wiki import ( + "bytes" + "encoding/csv" + ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/lex" "shylinux.com/x/icebergs/base/nfs" @@ -19,9 +22,28 @@ func init() { }}, }, Hand: func(m *ice.Message, arg ...string) { if !_wiki_list(m, m.CommandKey(), kit.Select(nfs.PWD, arg, 0)) { - m.CSV(m.Cmd(nfs.CAT, arg[0]).Result()) + CSV(m, m.Cmd(nfs.CAT, arg[0]).Result()) m.StatusTimeCount() } }}, }}) } + +func CSV(m *ice.Message, text string, head ...string) *ice.Message { + bio := bytes.NewBufferString(text) + r := csv.NewReader(bio) + + if len(head) == 0 { + head, _ = r.Read() + } + for { + line, e := r.Read() + if e != nil { + break + } + for i, k := range head { + m.Push(k, kit.Select("", line, i)) + } + } + return m +} diff --git a/core/wiki/field.go b/core/wiki/field.go index ceed2f82..09382702 100644 --- a/core/wiki/field.go +++ b/core/wiki/field.go @@ -5,6 +5,7 @@ import ( "strings" ice "shylinux.com/x/icebergs" + "shylinux.com/x/icebergs/base/aaa" "shylinux.com/x/icebergs/base/ctx" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" @@ -40,7 +41,7 @@ func _field_show(m *ice.Message, name, text string, arg ...string) { name = cmd.Help } }) - if !m.Spawn().Right(cmds[0]) { + if !aaa.Right(m.Spawn(), cmds[0]) { return } diff --git a/core/wiki/spark.go b/core/wiki/spark.go index 727dab9a..6c5b7d80 100644 --- a/core/wiki/spark.go +++ b/core/wiki/spark.go @@ -6,7 +6,6 @@ import ( ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/nfs" "shylinux.com/x/icebergs/base/ssh" - "shylinux.com/x/icebergs/base/web" kit "shylinux.com/x/toolkits" ) @@ -31,7 +30,7 @@ func _spark_show(m *ice.Message, name, text string, arg ...string) { } for _, l := range strings.Split(text, ice.NL) { - m.Echo(web.Format("div", web.Format("label", prompt), web.Format("span", l))) + m.Echo(Format("div", Format("label", prompt), Format("span", l))) } } @@ -62,11 +61,11 @@ func init() { list = append(list, "
") switch arg[0] { case SHELL: - list = append(list, web.Format("label", "$ ")) + list = append(list, Format("label", "$ ")) default: - list = append(list, web.Format("label", "> ")) + list = append(list, Format("label", "> ")) } - list = append(list, web.Format("span", l)) + list = append(list, Format("span", l)) list = append(list, "
") } list = append(list, "") @@ -133,3 +132,6 @@ func init() { )}, }}) } +func Format(tag string, arg ...ice.Any) string { + return kit.Format("<%s>%s", tag, strings.Join(kit.Simple(arg), ""), tag) +} diff --git a/core/wiki/wiki.go b/core/wiki/wiki.go index 8bf55618..b7379c83 100644 --- a/core/wiki/wiki.go +++ b/core/wiki/wiki.go @@ -5,6 +5,7 @@ import ( "strings" ice "shylinux.com/x/icebergs" + "shylinux.com/x/icebergs/base/ctx" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" "shylinux.com/x/icebergs/base/web" @@ -30,7 +31,7 @@ func _option(m *ice.Message, kind, name, text string, arg ...string) { } func _wiki_path(m *ice.Message, cmd string, arg ...string) string { - return path.Join(m.Option(ice.MSG_LOCAL), m.Conf(cmd, kit.Keym(nfs.PATH)), path.Join(arg...)) + return path.Join(m.Conf(cmd, kit.Keym(nfs.PATH)), path.Join(arg...)) } func _wiki_link(m *ice.Message, cmd string, text string) string { if !strings.HasPrefix(text, ice.HTTP) && !strings.HasPrefix(text, ice.PS) { @@ -62,11 +63,11 @@ func _wiki_save(m *ice.Message, cmd, name, text string, arg ...string) { m.Cmd(nfs.SAVE, name, text) } func _wiki_upload(m *ice.Message, cmd string, dir string) { - m.Upload(_wiki_path(m, cmd, dir)) + m.Cmdy(web.CACHE, web.UPLOAD_WATCH, _wiki_path(m, cmd, dir)) } func _wiki_template(m *ice.Message, cmd string, name, text string, arg ...string) { _option(m, cmd, name, strings.TrimSpace(text), arg...) - m.RenderTemplate(m.Conf(cmd, kit.Keym(nfs.TEMPLATE))) + m.RenderTemplate(m.Conf(cmd, kit.Keym(nfs.TEMPLATE)), &Message{m}) } const WIKI = "wiki" @@ -81,3 +82,30 @@ func init() { FEEL, DRAW, WORD, DATA, ) } + +type Message struct { + *ice.Message +} + +func (m *Message) OptionTemplate() string { + res := []string{`class="story"`} + for _, key := range kit.Split(ctx.STYLE) { + if m.Option(key) != "" { + res = append(res, kit.Format(`s="%s"`, key, m.Option(key))) + } + } + for _, key := range kit.Split("type,name,text") { + if key == mdb.TEXT && m.Option(mdb.TYPE) == "spark" { + continue + } + if m.Option(key) != "" { + res = append(res, kit.Format(`data-%s="%s"`, key, m.Option(key))) + } + } + kit.Fetch(m.Optionv("extra"), func(key string, value string) { + if value != "" { + res = append(res, kit.Format(`data-%s="%s"`, key, value)) + } + }) + return kit.Join(res, ice.SP) +} diff --git a/core/wiki/word.go b/core/wiki/word.go index ae620086..3b594076 100644 --- a/core/wiki/word.go +++ b/core/wiki/word.go @@ -10,6 +10,7 @@ import ( "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" "shylinux.com/x/icebergs/base/ssh" + "shylinux.com/x/icebergs/base/web" kit "shylinux.com/x/toolkits" ) @@ -46,7 +47,7 @@ func init() { }}, mdb.SEARCH: {Name: "search", Help: "搜索", Hand: func(m *ice.Message, arg ...string) { if arg[0] == mdb.FOREACH && arg[1] == "" { - m.PushSearch(mdb.TYPE, "shy", mdb.NAME, "src/main.shy", mdb.TEXT, m.MergeCmd("")) + m.PushSearch(mdb.TYPE, "shy", mdb.NAME, "src/main.shy", mdb.TEXT, web.MergeCmd(m, "")) } m.Cmd(mdb.SELECT, m.PrefixKey(), "", mdb.HASH).Tables(func(value ice.Maps) { if arg[1] == "" { @@ -88,7 +89,7 @@ func init() { if !kit.FileExists(arg[0]) && kit.FileExists(path.Join("src", arg[0])) { arg[0] = path.Join("src/", arg[0]) } - m.DisplayLocal("") + ctx.DisplayLocal(m, "") _word_show(m, arg[0]) } }}, diff --git a/data.go b/data.go index 5168faa9..9ceea38f 100644 --- a/data.go +++ b/data.go @@ -1,12 +1,9 @@ package ice import ( - "path" "strings" - "sync" kit "shylinux.com/x/toolkits" - "shylinux.com/x/toolkits/miss" ) func (m *Message) ActionKey() string { @@ -15,20 +12,12 @@ func (m *Message) ActionKey() string { func (m *Message) CommandKey() string { return strings.TrimSuffix(strings.TrimPrefix(m._key, PS), PS) } -func (m *Message) RoutePath(arg ...string) string { - return m.Target().RoutePath(arg...) -} func (m *Message) PrefixKey(arg ...string) string { return kit.Keys(m.Prefix(m.CommandKey()), arg) } func (m *Message) Prefix(arg ...string) string { return m.Target().PrefixKey(arg...) } -func (m *Message) ConfigSet(keys string, arg ...string) { - for i, k := range kit.Split(keys) { - m.Config(k, kit.Select("", arg, i)) - } -} func (m *Message) Config(key string, arg ...Any) string { if len(arg) > 0 { m.Conf(m.PrefixKey(), kit.Keym(key), arg[0]) @@ -41,107 +30,9 @@ func (m *Message) Configv(key string, arg ...Any) Any { } return m.Confv(m.PrefixKey(), kit.Keym(key)) } -func (m *Message) Configm(key string, arg ...Any) Map { - v, _ := m.Configv(key, arg...).(Map) - return v -} func (m *Message) ConfigSimple(key ...string) (list []string) { for _, k := range kit.Split(kit.Join(key)) { list = append(list, k, m.Config(k)) } return } -func (m *Message) ConfigOption(key ...string) { - for _, k := range kit.Split(kit.Join(key, FS)) { - m.Config(k, kit.Select(m.Config(k), m.Option(k))) - } -} -func (m *Message) Save(arg ...string) *Message { - if !strings.Contains(Getenv("ctx_daemon"), "ctx") { - return m - } - if len(arg) == 0 { - for k := range m.target.Configs { - arg = append(arg, k) - } - } - for i, k := range arg { - arg[i] = m.Prefix(k) - } - return m.Cmd(CONFIG, SAVE, m.Prefix(JSON), arg) -} -func (m *Message) Load(arg ...string) *Message { - if !strings.Contains(Getenv("ctx_daemon"), "ctx") { - return m - } - if len(arg) == 0 { - for k := range m.target.Configs { - arg = append(arg, k) - } - } - for i, k := range arg { - arg[i] = m.Prefix(k) - } - return m.Cmd(CONFIG, LOAD, m.Prefix(JSON), arg) -} - -func (m *Message) Richs(prefix string, chain Any, raw Any, cb Any) (res Map) { - cache := m.Confm(prefix, chain) - if cache == nil { - return nil - } - - switch cb := cb.(type) { - case func(*sync.Mutex, string, Map): - wg, mu := &sync.WaitGroup{}, &sync.Mutex{} - defer wg.Wait() - res = miss.Richs(path.Join(prefix, kit.Keys(chain)), cache, raw, func(key string, value Map) { - wg.Add(1) - m.Go(func() { - defer wg.Done() - cb(mu, key, value) - }) - }) - default: - res = miss.Richs(path.Join(prefix, kit.Keys(chain)), cache, raw, cb) - } - return res - -} -func (m *Message) Rich(prefix string, chain Any, data Any) string { - cache := m.Confm(prefix, chain) - if cache == nil { - cache = kit.Data() - m.Confv(prefix, chain, cache) - } - return miss.Rich(path.Join(prefix, kit.Keys(chain)), cache, data) -} -func (m *Message) Grow(prefix string, chain Any, data Any) int { - cache := m.Confm(prefix, chain) - if cache == nil { - cache = kit.Data() - m.Confv(prefix, chain, cache) - } - return miss.Grow(path.Join(prefix, kit.Keys(chain)), cache, data) -} -func (m *Message) Grows(prefix string, chain Any, match string, value string, cb Any) Map { - cache := m.Confm(prefix, chain) - if cache == nil { - return nil - } - - limit := kit.Int(m.Option(CACHE_LIMIT)) - if begin := kit.Int(m.Option(CACHE_BEGIN)); begin != 0 && limit > 0 { - count := kit.Int(m.Option(CACHE_COUNT, kit.Int(kit.Value(cache, kit.Keym("count"))))) - if begin > 0 { - m.Option(CACHE_OFFEND, count-begin-limit) - } else { - m.Option(CACHE_OFFEND, -begin-limit) - } - } - - return miss.Grows(path.Join(prefix, kit.Keys(chain)), cache, - kit.Int(kit.Select("0", strings.TrimPrefix(m.Option(CACHE_OFFEND), "-"))), - kit.Int(kit.Select("10", m.Option(CACHE_LIMIT))), - match, value, cb) -} diff --git a/exec.go b/exec.go index 22b07277..90089c5e 100644 --- a/exec.go +++ b/exec.go @@ -3,8 +3,6 @@ package ice import ( "errors" "io" - "path" - "strings" "time" kit "shylinux.com/x/toolkits" @@ -23,7 +21,7 @@ func (m *Message) TryCatch(msg *Message, silent bool, hand ...func(msg *Message) m.Log(LOG_WARN, "catch: %s %s", e, fileline) m.Log("stack", msg.FormatStack(2, 100)) m.Log(LOG_WARN, "catch: %s %s", e, fileline) - m.Echo("%v", e) + m.Result(ErrWarn, e) if len(hand) > 1 { m.TryCatch(msg, silent, hand[1:]...) } else if !silent { @@ -38,16 +36,16 @@ func (m *Message) TryCatch(msg *Message, silent bool, hand ...func(msg *Message) return m } func (m *Message) Assert(expr Any) bool { - switch expr := expr.(type) { + switch e := expr.(type) { case nil: return true case error: case bool: - if expr == true { + if e == true { return true } default: - expr = errors.New(kit.Format("error: %v", expr)) + expr = errors.New(kit.Format("error: %v", e)) } m.Result(ErrWarn, expr) panic(expr) @@ -61,43 +59,8 @@ func (m *Message) Sleep(d string, arg ...Any) *Message { func (m *Message) Sleep300ms(arg ...Any) *Message { return m.Sleep("300ms", arg...) } func (m *Message) Sleep30ms(arg ...Any) *Message { return m.Sleep("30ms", arg...) } func (m *Message) Sleep3s(arg ...Any) *Message { return m.Sleep("3s", arg...) } -func (m *Message) Sleep30s(arg ...Any) *Message { return m.Sleep("30s", arg...) } -func (m *Message) Call(sync bool, cb func(*Message) *Message) *Message { - wait := make(chan bool, 2) - - p := kit.Select("10s", m.Option("timeout")) - t := time.AfterFunc(kit.Duration(p), func() { - m.Warn(true, ErrNotValid, m.Detailv()) - m.Back(nil) - wait <- false - }) - - m.cb = func(res *Message) *Message { - if res = cb(res); sync { - wait <- true - t.Stop() - } - return res - } - - if sync { - <-wait - } else { - t.Stop() - } - return m -} -func (m *Message) Back(res *Message) *Message { - if m.cb != nil { - if sub := m.cb(res); m.message != nil { - m.message.Back(sub) - } - } - return m -} - -func (m *Message) Go(cb Any, arg ...string) *Message { - task.Put(kit.Select(kit.FileLine(cb, 3), arg, 0), func(task *task.Task) error { +func (m *Message) Go(cb Any) *Message { + task.Put(kit.FileLine(cb, 3), func(task *task.Task) error { m.TryCatch(m, true, func(m *Message) { switch cb := cb.(type) { case func(*Message): @@ -112,38 +75,3 @@ func (m *Message) Go(cb Any, arg ...string) *Message { }) return m } - -func (m *Message) Watch(key string, arg ...string) *Message { - if len(arg) == 0 { - arg = append(arg, m.Prefix(AUTO)) - } - m.Cmd(EVENT, ACTION, LISTEN, EVENT, key, CMD, kit.Join(arg, SP)) - return m -} -func (m *Message) Event(key string, arg ...string) *Message { - m.Cmd(EVENT, ACTION, HAPPEN, EVENT, key, arg) - return m -} -func (m *Message) Right(arg ...Any) bool { - key := path.Join(strings.ReplaceAll(kit.Keys(arg...), PT, PS)) - key = strings.TrimPrefix(strings.TrimSuffix(strings.ReplaceAll(key, PS, PT), PT), PT) - return m.Option(MSG_USERROLE) == ROOT || !m.Warn(m.Cmdx(ROLE, RIGHT, m.Option(MSG_USERROLE), key) != OK, - ErrNotRight, kit.Join(kit.Simple(arg), PT), USERROLE, m.Option(MSG_USERROLE), FILELINE, kit.FileLine(2, 3)) -} -func (m *Message) Space(arg Any) []string { - if arg == nil || arg == "" || kit.Format(arg) == Info.NodeName { - return nil - } - return []string{SPACE, kit.Format(arg)} -} -func (m *Message) PodCmd(arg ...Any) bool { - if pod := m.Option(POD); pod != "" { - if m.Option(POD, ""); m.Option(MSG_UPLOAD) != "" { - msg := m.Cmd(CACHE, "upload") - m.Option(MSG_UPLOAD, msg.Append(HASH), msg.Append(NAME), msg.Append("size")) - } - m.Cmdy(append(kit.List(SPACE, pod), arg...)) - return true - } - return false -} diff --git a/info.go b/info.go index cc7f188a..7027db34 100644 --- a/info.go +++ b/info.go @@ -1,13 +1,5 @@ package ice -import ( - "os" - "path" - "strings" - - kit "shylinux.com/x/toolkits" -) - type MakeInfo struct { Path string Time string @@ -38,13 +30,13 @@ var Info = struct { PidPath string Help string - cans string - Route Maps // 路由命令 - File Maps // 文件命令 - Pack map[string][]byte // 打包文件 + Route Maps // 路由命令 + File Maps // 文件命令 names Map render map[string]func(*Message, string, ...Any) string + Save func(m *Message, key ...string) *Message + Load func(m *Message, key ...string) *Message Log func(m *Message, p, l, s string) }{ Help: ` @@ -54,88 +46,13 @@ var Info = struct { report: shylinuxc@gmail.com server: https://shylinux.com source: https://shylinux.com/x/icebergs -`, - cans: ` - - - - - - - - - `, Route: Maps{}, File: Maps{}, - Pack: map[string][]byte{}, names: Map{}, render: map[string]func(*Message, string, ...Any) string{}, + Save: func(m *Message, key ...string) *Message { return m }, + Load: func(m *Message, key ...string) *Message { return m }, Log: func(m *Message, p, l, s string) {}, } - -func FileURI(dir string) string { - if strings.Contains(dir, "go/pkg/mod") { - return path.Join("/require", strings.Split(dir, "go/pkg/mod")[1]) - } - if Info.Make.Path != "" && strings.HasPrefix(dir, Info.Make.Path+PS) { - dir = strings.TrimPrefix(dir, Info.Make.Path+PS) - } - if strings.HasPrefix(dir, kit.Path("")+PS) { - dir = strings.TrimPrefix(dir, kit.Path("")+PS) - } - if strings.HasPrefix(dir, SRC) { - return path.Join("/require", dir) - } - if strings.HasPrefix(dir, USR) { - return path.Join("/require", dir) - } - if kit.FileExists(path.Join("src", dir)) { - return path.Join("/require/src/", dir) - } - return dir -} -func FileCmd(dir string) string { - dir = strings.Split(dir, DF)[0] - dir = strings.ReplaceAll(dir, ".js", ".go") - dir = strings.ReplaceAll(dir, ".sh", ".go") - return FileURI(dir) -} -func AddFileCmd(dir, key string) { - Info.File[FileCmd(dir)] = key -} -func GetFileCmd(dir string) string { - if strings.HasPrefix(dir, "require/") { - dir = "/" + dir - } - for _, dir := range []string{dir, path.Join("/require/", Info.Make.Module, dir), path.Join("/require/", Info.Make.Module, SRC, dir)} { - if cmd, ok := Info.File[FileCmd(dir)]; ok { - return cmd - } - p := path.Dir(dir) - if cmd, ok := Info.File[FileCmd(path.Join(p, path.Base(p)+".go"))]; ok { - return cmd - } - for k, v := range Info.File { - if strings.HasPrefix(k, p) { - return v - } - } - } - return "" -} -func FileRequire(n int) string { - p := kit.Split(kit.FileLine(n, 100), DF)[0] - if strings.Contains(p, "go/pkg/mod") { - return path.Join("/require", strings.Split(p, "go/pkg/mod")[1]) - } - return path.Join("/require/"+kit.ModPath(n), path.Base(p)) -} -func Getenv(key string) string { - switch key { - case "ctx_daemon": - return kit.Select("ctx,log,gdb,ssh", os.Getenv(key)) - } - return os.Getenv(key) -} diff --git a/init.go b/init.go index 13d34824..c8a05f7f 100644 --- a/init.go +++ b/init.go @@ -28,10 +28,10 @@ func (f *Frame) Begin(m *Message, arg ...string) Server { } func (f *Frame) Start(m *Message, arg ...string) bool { m.Cap(CTX_STREAM, strings.Split(m.Time(), SP)[1]) - m.Cmdy("mdb._init") + m.Cmdy(kit.Keys(MDB, CTX_INIT)) m.Cmdy(INIT, arg) - for _, k := range kit.Split(Getenv(CTX_DAEMON)) { + for _, k := range kit.Split(kit.Select("ctx,log,gdb,ssh", os.Getenv(CTX_DAEMON))) { m.Start(k) } m.Cmd(arg) @@ -49,9 +49,9 @@ func (f *Frame) Close(m *Message, arg ...string) bool { return true } -var Index = &Context{Name: ICE, Help: "冰山模块", Configs: map[string]*Config{ +var Index = &Context{Name: ICE, Help: "冰山模块", Configs: Configs{ HELP: {Value: kit.Data(INDEX, Info.Help)}, -}, Commands: map[string]*Command{ +}, Commands: Commands{ CTX_INIT: {Hand: func(m *Message, arg ...string) { m.root.Travel(func(p *Context, c *Context) { if cmd, ok := c.Commands[CTX_INIT]; ok && p != nil { @@ -61,15 +61,18 @@ var Index = &Context{Name: ICE, Help: "冰山模块", Configs: map[string]*Confi }}, INIT: {Name: "init", Help: "启动", Hand: func(m *Message, arg ...string) { m.root.Cmd(CTX_INIT) - m.Cmd(SOURCE, ETC_INIT_SHY) + m.Cmd("source", ETC_INIT_SHY) }}, HELP: {Name: "help", Help: "帮助", Hand: func(m *Message, arg ...string) { m.Echo(m.Config(INDEX)) }}, - EXIT: {Name: "exit", Help: "结束", Hand: func(m *Message, arg ...string) { + QUIT: {Name: "quit", Help: "结束", Hand: func(m *Message, arg ...string) { + os.Exit(0) + }}, + EXIT: {Name: "exit", Help: "退出", Hand: func(m *Message, arg ...string) { defer m.Target().Close(m.root.Spawn(), arg...) m.root.Option(EXIT, kit.Select("0", arg, 0)) - m.Cmd(SOURCE, ETC_EXIT_SHY) + m.Cmd("source", ETC_EXIT_SHY) m.root.Cmd(CTX_EXIT) }}, CTX_EXIT: {Hand: func(m *Message, arg ...string) { @@ -91,16 +94,16 @@ func init() { Index.root, Pulse.root = Index, Pulse } func Run(arg ...string) string { if len(arg) == 0 { // 进程参数 - arg = kit.Simple(arg, os.Args[1:], kit.Split(kit.Env("ctx_arg"))) + arg = kit.Simple(arg, os.Args[1:], kit.Split(os.Getenv(CTX_ARG))) } Pulse.meta[MSG_DETAIL] = arg switch Index.Merge(Index).Begin(Pulse.Spawn(), arg...); kit.Select("", arg, 0) { - case SERVE, SPACE: // 启动服务 + case "serve", "space": // 启动服务 if Index.Start(Pulse, arg...) { conf.Wait() - os.Exit(kit.Int(Pulse.Option(EXIT))) println() + os.Exit(kit.Int(Pulse.Option(EXIT))) } default: // 执行命令 if logs.Disable(true); len(arg) == 0 { diff --git a/lock.go b/lock.go deleted file mode 100644 index d9f76ae3..00000000 --- a/lock.go +++ /dev/null @@ -1,36 +0,0 @@ -package ice - -import ( - "sync" - - kit "shylinux.com/x/toolkits" -) - -var lock = map[string]*sync.RWMutex{} -var _lock = sync.Mutex{} - -func (m *Message) _lock(key string) *sync.RWMutex { - if key == "" { - key = m.PrefixKey() - } - - _lock.Lock() - defer _lock.Unlock() - - l, ok := lock[key] - if !ok { - l = &sync.RWMutex{} - lock[key] = l - } - return l -} -func (m *Message) Lock(arg ...Any) func() { - l := m._lock(kit.Keys(arg...)) - l.Lock() - return func() { l.Unlock() } -} -func (m *Message) RLock(arg ...Any) func() { - l := m._lock(kit.Keys(arg...)) - l.RLock() - return func() { l.RUnlock() } -} diff --git a/logs.go b/logs.go index 21d0314d..0d6bec1a 100644 --- a/logs.go +++ b/logs.go @@ -10,46 +10,13 @@ import ( "shylinux.com/x/toolkits/logs" ) -func (m *Message) log(level string, str string, arg ...Any) *Message { - _source := logs.FileLineMeta(logs.FileLine(3, 3)) - if Info.Log != nil { - Info.Log(m, m.FormatPrefix(), level, logs.Format(str, append(arg, _source)...)) // 日志分流 - } - - // 日志颜色 - prefix, suffix := "", "" - if Info.Colors { - switch level { - case LOG_CREATE, LOG_INSERT, LOG_MODIFY, LOG_EXPORT, LOG_IMPORT: - prefix, suffix = "\033[36;44m", "\033[0m" - case LOG_CMDS, LOG_START, LOG_SERVE: - prefix, suffix = "\033[32m", "\033[0m" - case LOG_WARN, LOG_ERROR, LOG_CLOSE: - prefix, suffix = "\033[31m", "\033[0m" - case LOG_AUTH, LOG_COST: - prefix, suffix = "\033[33m", "\033[0m" - } - } - - // 长度截断 - switch level { - case LOG_INFO, LOG_SEND, LOG_RECV: - if len(str) > 4096 { - str = str[:4096] - } - } - - // 输出日志 - logs.Infof(str, append(arg, logs.PrefixMeta(kit.Format("%02d %4s->%-4s %s%s ", m.code, m.source.Name, m.target.Name, prefix, level)), logs.SuffixMeta(suffix), _source)...) - return m -} func (m *Message) join(arg ...Any) (string, []Any) { list, meta := []string{}, []Any{} for i := 0; i < len(arg); i += 2 { switch v := arg[i].(type) { case logs.Meta: - i-- meta = append(meta, v) + i-- continue } if key := strings.TrimSpace(kit.Format(arg[i])); i == len(arg)-1 { @@ -66,10 +33,51 @@ func (m *Message) join(arg ...Any) (string, []Any) { } return kit.Join(list, SP), meta } +func (m *Message) log(level string, str string, arg ...Any) *Message { + _source := logs.FileLineMeta(logs.FileLine(3, 3)) + Info.Log(m, m.FormatPrefix(), level, logs.Format(str, append(arg, _source)...)) // 日志回调 + // 日志颜色 + prefix, suffix := "", "" + if Info.Colors { + switch level { + case LOG_CMDS: + prefix, suffix = "\033[32m", "\033[0m" + case LOG_AUTH, LOG_COST: + prefix, suffix = "\033[33m", "\033[0m" + case LOG_WARN: + prefix, suffix = "\033[31m", "\033[0m" + } + } + + // 长度截断 + switch level { + case LOG_INFO: + if len(str) > 4096 { + str = str[:4096] + } + } + + // 输出日志 + logs.Infof(str, append(arg, logs.PrefixMeta(kit.Format("%02d %4s->%-4s %s%s ", m.code, m.source.Name, m.target.Name, prefix, level)), logs.SuffixMeta(suffix), _source)...) + return m +} func (m *Message) Log(level string, str string, arg ...Any) *Message { return m.log(level, str, arg...) } +func (m *Message) Logs(level string, arg ...Any) *Message { + str, meta := m.join(arg...) + return m.log(level, str, meta...) +} + +func (m *Message) Cost(arg ...Any) *Message { + str, meta := m.join(arg...) + if len(arg) == 0 { + str = kit.Join(m.meta[MSG_DETAIL], SP) + } + list := []string{m.FormatCost(), str} + return m.log(LOG_COST, kit.Join(list, SP), meta...) +} func (m *Message) Info(str string, arg ...Any) *Message { return m.log(LOG_INFO, str, arg...) } @@ -93,17 +101,11 @@ func (m *Message) Warn(err Any, arg ...Any) bool { m.error(arg...) return true } -func (m *Message) error(arg ...Any) { - if len(arg) == 0 { - arg = append(arg, "", "") - } else if len(arg) == 1 { - arg = append(arg, "") +func (m *Message) Debug(str string, arg ...Any) { + if str == "" { + str = m.FormatMeta() } - str, meta := m.join(arg[2:]...) - m.meta[MSG_RESULT] = kit.Simple(ErrWarn, arg[0], arg[1], str, meta) -} -func (m *Message) ErrorNotImplement(arg ...Any) { - m.Error(true, append(kit.List(ErrNotImplement), arg...)...) + m.log(LOG_DEBUG, str, arg...) } func (m *Message) Error(err bool, arg ...Any) bool { if err { @@ -116,72 +118,27 @@ func (m *Message) Error(err bool, arg ...Any) bool { } return false } -func (m *Message) Debug(str string, arg ...Any) { - if str == "" { - str = m.FormatMeta() - } - m.log(LOG_DEBUG, str, arg...) +func (m *Message) ErrorNotImplement(arg ...Any) { + m.Error(true, append(kit.List(ErrNotImplement), arg...)...) } -func (m *Message) Cost(arg ...Any) *Message { - str, meta := m.join(arg...) +func (m *Message) error(arg ...Any) { if len(arg) == 0 { - str = kit.Join(m.meta[MSG_DETAIL], SP) + arg = append(arg, "", "") + } else if len(arg) == 1 { + arg = append(arg, "") } - list := []string{m.FormatCost(), str} - return m.log(LOG_COST, kit.Join(list, SP), meta...) + str, meta := m.join(arg[2:]...) + m.meta[MSG_RESULT] = kit.Simple(ErrWarn, arg[0], arg[1], str, meta) } -func (m *Message) Logs(level string, arg ...Any) *Message { - str, meta := m.join(arg...) - return m.log(level, str, meta...) -} -func (m *Message) Log_AUTH(arg ...Any) *Message { - str, meta := m.join(arg...) - return m.log(LOG_AUTH, str, meta...) -} -func (m *Message) Log_SEND(arg ...Any) *Message { - str, meta := m.join(arg...) - return m.log(LOG_AUTH, str, meta...) -} -func (m *Message) Log_CREATE(arg ...Any) *Message { - str, meta := m.join(arg...) - return m.log(LOG_CREATE, str, meta...) -} -func (m *Message) Log_REMOVE(arg ...Any) *Message { - str, meta := m.join(arg...) - return m.log(LOG_REMOVE, str, meta...) -} -func (m *Message) Log_INSERT(arg ...Any) *Message { - str, meta := m.join(arg...) - return m.log(LOG_INSERT, str, meta...) -} -func (m *Message) Log_DELETE(arg ...Any) *Message { - str, meta := m.join(arg...) - return m.log(LOG_DELETE, str, meta...) -} -func (m *Message) Log_MODIFY(arg ...Any) *Message { - str, meta := m.join(arg...) - return m.log(LOG_MODIFY, str, meta...) -} -func (m *Message) Log_SELECT(arg ...Any) *Message { - str, meta := m.join(arg...) - return m.log(LOG_SELECT, str, meta...) -} -func (m *Message) Log_EXPORT(arg ...Any) *Message { - str, meta := m.join(arg...) - return m.log(LOG_EXPORT, str, meta...) -} -func (m *Message) Log_IMPORT(arg ...Any) *Message { - str, meta := m.join(arg...) - return m.log(LOG_IMPORT, str, meta...) +func (m *Message) IsErrNotFound() bool { return m.IsErr(ErrNotFound) } +func (m *Message) IsErr(arg ...string) bool { + return len(arg) > 0 && m.Result(1) == arg[0] || len(arg) == 0 && m.Result(0) == ErrWarn } func (m *Message) FormatPrefix() string { return kit.Format("%s %d %s->%s", logs.FmtTime(logs.Now()), m.code, m.source.Name, m.target.Name) } -func (m *Message) FormatTime() string { - return m.Time() -} func (m *Message) FormatShip() string { return kit.Format("%s->%s", m.source.Name, m.target.Name) } @@ -197,35 +154,6 @@ func (m *Message) FormatMeta() string { func (m *Message) FormatsMeta() string { return kit.Formats(m.meta) } -func (m *Message) FormatStack(s, n int) string { - pc := make([]uintptr, n+10) - frames := runtime.CallersFrames(pc[:runtime.Callers(s+1, pc)]) - - list := []string{} - for { - frame, more := frames.Next() - file := kit.Slice(kit.Split(frame.File, PS, PS), -1)[0] - name := kit.Slice(kit.Split(frame.Function, PS, PS), -1)[0] - - switch ls := kit.Split(name, PT, PT); kit.Select("", ls, 0) { - case "reflect", "runtime", "http", "task", "icebergs": - default: - switch kit.Select("", ls, 1) { - // case "(*Frame)": - default: - list = append(list, kit.Format("%s:%d\t%s", file, frame.Line, name)) - } - } - - if len(list) >= n { - break - } - if !more { - break - } - } - return kit.Join(list, NL) -} func (m *Message) FormatChain() string { ms := []*Message{} for msg := m; msg != nil; msg = msg.message { @@ -254,8 +182,28 @@ func (m *Message) FormatChain() string { } return kit.Join(meta, NL) } +func (m *Message) FormatStack(s, n int) string { + pc := make([]uintptr, n+10) + frames := runtime.CallersFrames(pc[:runtime.Callers(s+1, pc)]) -func (m *Message) IsErr(arg ...string) bool { - return len(arg) > 0 && m.Result(1) == arg[0] || m.Result(0) == ErrWarn + list := []string{} + for { + frame, more := frames.Next() + file := kit.Slice(kit.Split(frame.File, PS, PS), -1)[0] + name := kit.Slice(kit.Split(frame.Function, PS, PS), -1)[0] + + switch ls := kit.Split(name, PT, PT); kit.Select("", ls, 0) { + case "reflect", "runtime", "http", "task", "icebergs": + default: + list = append(list, kit.Format("%s:%d\t%s", file, frame.Line, name)) + } + + if len(list) >= n { + break + } + if !more { + break + } + } + return kit.Join(list, NL) } -func (m *Message) IsErrNotFound() bool { return m.Result(1) == ErrNotFound } diff --git a/meta.go b/meta.go index 19273eb1..a95553d3 100644 --- a/meta.go +++ b/meta.go @@ -130,7 +130,7 @@ func (m *Message) Push(key string, value Any, arg ...Any) *Message { var v Any switch k { case KEY, HASH: - if key != "" && key != CACHE_DETAIL { + if key != "" && key != FIELDS_DETAIL { v = key break } @@ -142,7 +142,7 @@ func (m *Message) Push(key string, value Any, arg ...Any) *Message { if v = kit.Value(value, k); v != nil { break } - if v = kit.Value(value, kit.Keys("extra", k)); v != nil { + if v = kit.Value(value, kit.Keys(EXTRA, k)); v != nil { break } if v = val[k]; v != nil { @@ -151,14 +151,14 @@ func (m *Message) Push(key string, value Any, arg ...Any) *Message { if v = kit.Value(val, k); v != nil { break } - if v = kit.Value(val, kit.Keys("extra", k)); v != nil { + if v = kit.Value(val, kit.Keys(EXTRA, k)); v != nil { break } } // 追加数据 switch v := kit.Format(v); key { - case CACHE_DETAIL: + case FIELDS_DETAIL: m.Add(MSG_APPEND, KEY, k) m.Add(MSG_APPEND, VALUE, v) default: @@ -261,8 +261,14 @@ func (m *Message) Table(cbs ...func(index int, value Maps, head []string)) *Mess return m } + const ( + TABLE_SPACE = "table.space" + TABLE_ROW_SEP = "table.row_sep" + TABLE_COL_SEP = "table.col_sep" + TABLE_COMPACT = "table.compact" + ) //计算列宽 - space := kit.Select(SP, m.Option("table.space")) + space := kit.Select(SP, m.Option(TABLE_SPACE)) depth, width := 0, map[string]int{} for _, k := range m.meta[MSG_APPEND] { if len(m.meta[k]) > depth { @@ -277,9 +283,9 @@ func (m *Message) Table(cbs ...func(index int, value Maps, head []string)) *Mess } // 回调函数 - rows := kit.Select(NL, m.Option("table.row_sep")) - cols := kit.Select(SP, m.Option("table.col_sep")) - compact := m.Option("table.compact") == TRUE + rows := kit.Select(NL, m.Option(TABLE_ROW_SEP)) + cols := kit.Select(SP, m.Option(TABLE_COL_SEP)) + compact := m.Option(TABLE_COMPACT) == TRUE cb := func(value Maps, field []string, index int) bool { for i, v := range field { if k := m.meta[MSG_APPEND][i]; compact { @@ -325,16 +331,28 @@ func (m *Message) Sort(key string, arg ...string) *Message { if key = ls[0]; m.FieldsIsDetail() && key != KEY { return m } + const ( + STR = "str" + INT = "int" + TIME = "time" + + TIME_R = "time_r" + INT_R = "int_r" + STR_R = "str_r" + + GT = ">" + LT = "<" + ) // 排序方法 - cmp := "str" + cmp := STR if len(arg) > 0 && arg[0] != "" { cmp = arg[0] } else { - cmp = "int" + cmp = INT for _, v := range m.meta[key] { if _, e := strconv.Atoi(v); e != nil { - cmp = "str" + cmp = STR } } } @@ -344,13 +362,13 @@ func (m *Message) Sort(key string, arg ...string) *Message { table := []Maps{} m.Table(func(index int, value Maps, head []string) { switch table = append(table, value); cmp { - case "int": + case INT: number[index] = kit.Int64(value[key]) - case "int_r": + case INT_R: number[index] = -kit.Int64(value[key]) - case "time": + case TIME: number[index] = int64(kit.Time(value[key])) - case "time_r": + case TIME_R: number[index] = -int64(kit.Time(value[key])) } }) @@ -362,10 +380,10 @@ func (m *Message) Sort(key string, arg ...string) *Message { if table[i][ls[k]] == table[j][ls[k]] { continue } - if op == ">" && table[i][ls[k]] > table[j][ls[k]] { + if op == GT && table[i][ls[k]] > table[j][ls[k]] { return true } - if op == "<" && table[i][ls[k]] < table[j][ls[k]] { + if op == LT && table[i][ls[k]] < table[j][ls[k]] { return true } return false @@ -378,22 +396,22 @@ func (m *Message) Sort(key string, arg ...string) *Message { for j := i + 1; j < len(table); j++ { swap := false switch cmp { - case "", "str": + case "", STR: if table[i][key] > table[j][key] { swap = true - } else if table[i][key] == table[j][key] && compare(i, j, ">") { + } else if table[i][key] == table[j][key] && compare(i, j, GT) { swap = true } - case "str_r": + case STR_R: if table[i][key] < table[j][key] { swap = true - } else if table[i][key] == table[j][key] && compare(i, j, "<") { + } else if table[i][key] == table[j][key] && compare(i, j, LT) { swap = true } default: if number[i] > number[j] { swap = true - } else if table[i][key] == table[j][key] && compare(i, j, ">") { + } else if table[i][key] == table[j][key] && compare(i, j, GT) { swap = true } } diff --git a/misc.go b/misc.go index dfac6785..033d1cd0 100644 --- a/misc.go +++ b/misc.go @@ -1,34 +1,13 @@ package ice import ( - "bytes" - "encoding/csv" "reflect" "strings" kit "shylinux.com/x/toolkits" - "shylinux.com/x/toolkits/file" "shylinux.com/x/toolkits/logs" ) -func (m *Message) CSV(text string, head ...string) *Message { - bio := bytes.NewBufferString(text) - r := csv.NewReader(bio) - - if len(head) == 0 { - head, _ = r.Read() - } - for { - line, e := r.Read() - if e != nil { - break - } - for i, k := range head { - m.Push(k, kit.Select("", line, i)) - } - } - return m -} func (m *Message) Split(str string, arg ...string) *Message { // field sp nl m.Set(MSG_APPEND).Set(MSG_RESULT) field := kit.Select("", arg, 0) @@ -76,15 +55,15 @@ func (m *Message) Split(str string, arg ...string) *Message { // field sp nl func (m *Message) SplitIndex(str string, arg ...string) *Message { return m.Split(str, kit.Simple(INDEX, arg)...) } +func (m *Message) PushRecord(value Any, arg ...string) *Message { + return m.Push("", value, kit.Split(kit.Join(arg))) +} func (m *Message) PushDetail(value Any, arg ...string) *Message { switch v := value.(type) { case string: value = kit.UnMarshal(v) } - return m.Push(CACHE_DETAIL, value, kit.Split(kit.Join(arg))) -} -func (m *Message) PushRecord(value Any, arg ...string) *Message { - return m.Push("", value, kit.Split(kit.Join(arg))) + return m.Push(FIELDS_DETAIL, value, kit.Split(kit.Join(arg))) } func (m *Message) ToLowerAppend(arg ...string) *Message { @@ -108,14 +87,6 @@ func (m *Message) RenameAppend(arg ...string) *Message { // [from to]... } return m } -func (m *Message) OptionFiles(f ...file.File) file.File { - if len(f) > 1 { - m.Optionv(MSG_FILES, file.NewMultiFile(f...)) - } else if len(f) > 0 { - m.Optionv(MSG_FILES, f[0]) - } - return m.Optionv(MSG_FILES).(file.File) -} func (m *Message) AppendSimple(key ...string) (res []string) { if len(key) == 0 { if m.FieldsIsDetail() { @@ -166,7 +137,7 @@ func (m *Message) Design(action Any, help string, input ...Any) { continue } kit.Fetch(kit.KeyValue(nil, "", input), func(k string, v Any) { - list = append(list, kit.Dict(NAME, k, TYPE, "text", VALUE, v)) + list = append(list, kit.Dict(NAME, k, TYPE, TEXT, VALUE, v)) }) default: m.ErrorNotImplement(input) @@ -186,27 +157,30 @@ func (m *Message) _command(arg ...Any) *Message { _source := logs.FileLine(3, 3) for _, v := range arg { switch val := v.(type) { - case logs.Meta: - if val.Key == "fileline" { - _source = val.Value + case string: + args = append(args, v) + case Maps: + for k, v := range val { + opts[k] = v + } + case Map: + for k, v := range val { + opts[k] = v } case Option: opts[val.Name] = val.Value case *Option: opts[val.Name] = val.Value - case Map: - for k, v := range val { - opts[k] = v + + case logs.Meta: + if val.Key == "fileline" { + _source = val.Value } - case Maps: - for k, v := range val { - opts[k] = v - } - case string: - args = append(args, v) case func(int, Maps, []string): defer func() { m.Table(val) }() + case func(Maps): + defer func() { m.Tables(val) }() default: if reflect.TypeOf(val).Kind() == reflect.Func { cbs = val @@ -224,9 +198,6 @@ func (m *Message) _command(arg ...Any) *Message { if len(list) == 0 { return m } - if list[0] == "" { - list[0] = m.PrefixKey() - } ok := false run := func(msg *Message, ctx *Context, cmd *Command, key string, arg ...string) { @@ -239,12 +210,12 @@ func (m *Message) _command(arg ...Any) *Message { // 执行命令 msg._source = _source - key = kit.Slice(strings.Split(key, PT), -1)[0] m.TryCatch(msg, true, func(msg *Message) { m = ctx._command(msg, cmd, key, arg...) }) } // 查找命令 if list[0] == "" { + list[0] = m._key run(m.Spawn(), m.target, m._cmd, list[0], list[1:]...) } else if cmd, ok := m.target.Commands[strings.TrimPrefix(list[0], m.target.Cap(CTX_FOLLOW)+PT)]; ok { run(m.Spawn(), m.target, cmd, list[0], list[1:]...) @@ -255,14 +226,15 @@ func (m *Message) _command(arg ...Any) *Message { run(m.Spawn(s), s, cmd, key, list[1:]...) }) } - m.Warn(!ok, ErrNotFound, kit.Format(list)) return m } func (c *Context) _command(m *Message, cmd *Command, key string, arg ...string) *Message { + key = kit.Slice(strings.Split(key, PT), -1)[0] if m._key, m._cmd = key, cmd; cmd == nil { return m } + if m.Hand, m.meta[MSG_DETAIL] = true, kit.Simple(key, arg); cmd.Actions != nil { if len(arg) > 1 && arg[0] == ACTION { if h, ok := cmd.Actions[arg[1]]; ok { @@ -298,7 +270,6 @@ func (c *Context) _action(m *Message, cmd *Command, key string, sub string, h *A for i, v := range h.List { name := kit.Format(kit.Value(v, NAME)) value := kit.Format(kit.Value(v, VALUE)) - if i == 0 && len(arg) > 0 && arg[0] != name { order = true } @@ -318,10 +289,45 @@ func (c *Context) _action(m *Message, cmd *Command, key string, sub string, h *A m._target = kit.FileLine(cmd.Hand, 3) m.Log(LOG_CMDS, "%s.%s %s %d %v", c.Name, key, sub, len(arg), arg, logs.FileLineMeta(kit.Select(m._target, m._source, m.target.Name == MDB))) + h.Hand(m, arg...) return m } - +func MergeAction(list ...Any) Actions { + if len(list) == 0 { + return nil + } + base := list[0].(Actions) + for _, from := range list[1:] { + switch from := from.(type) { + case Actions: + for k, v := range from { + if h, ok := base[k]; !ok { + base[k] = v + } else if h.Hand == nil { + h.Hand = v.Hand + } else if k == CTX_INIT { + last := base[k].Hand + prev := v.Hand + base[k].Hand = func(m *Message, arg ...string) { + prev(m, arg...) + last(m, arg...) + } + } + } + case string: + base[CTX_INIT] = &Action{Hand: func(m *Message, arg ...string) { + m.Search(from, func(p *Context, s *Context, key string, cmd *Command) { + MergeAction(base, cmd.Actions) + m.target.Merge(m.target) + }) + }} + default: + Pulse.ErrorNotImplement(from) + } + } + return base +} func SplitCmd(name string) (list []Any) { const ( TEXT = "text" @@ -400,38 +406,3 @@ func SplitCmd(name string) (list []Any) { } return list } -func MergeAction(list ...Any) map[string]*Action { - if len(list) == 0 { - return nil - } - base := list[0].(map[string]*Action) - for _, from := range list[1:] { - switch from := from.(type) { - case map[string]*Action: - for k, v := range from { - if h, ok := base[k]; !ok { - base[k] = v - } else if h.Hand == nil { - h.Hand = v.Hand - } else if k == CTX_INIT { - last := base[k].Hand - prev := v.Hand - base[k].Hand = func(m *Message, arg ...string) { - prev(m, arg...) - last(m, arg...) - } - } - } - case string: - base[CTX_INIT] = &Action{Hand: func(m *Message, arg ...string) { - m.Search(from, func(p *Context, s *Context, key string, cmd *Command) { - MergeAction(base, cmd.Actions) - m.target.Merge(m.target) - }) - }} - default: - Pulse.ErrorNotImplement(from) - } - } - return base -} diff --git a/misc/alpha/alpha.go b/misc/alpha/alpha.go index 356c518b..71ee2a46 100644 --- a/misc/alpha/alpha.go +++ b/misc/alpha/alpha.go @@ -9,6 +9,7 @@ import ( "shylinux.com/x/icebergs/base/cli" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" + "shylinux.com/x/icebergs/core/wiki" kit "shylinux.com/x/toolkits" ) @@ -43,7 +44,7 @@ func (a alpha) Load(m *ice.Message, arg ...string) { // 保存词库 m.Conf(m.PrefixKey(), kit.Keys(name, kit.Keym(mdb.LIMIT)), 0) m.Conf(m.PrefixKey(), kit.Keys(name, kit.Keym(mdb.LEAST)), 0) - m.Echo("%s: %d", name, m.Grow(m.PrefixKey(), name, kit.Dict(WORD, ice.SP))) + m.Echo("%s: %d", name, mdb.Grow(m.Message, m.PrefixKey(), name, kit.Dict(WORD, ice.SP))) } func (a alpha) List(m *ice.Message, arg ...string) { if len(arg) < 2 || arg[1] == "" { @@ -71,7 +72,7 @@ func (a alpha) List(m *ice.Message, arg ...string) { // 搜索词汇 msg := m.Cmd(cli.SYSTEM, "grep", "-rih", arg[1], m.Config(mdb.STORE)) - msg.CSV(msg.Result(), kit.Split(m.Config(mdb.FIELD))...).Tables(func(value ice.Maps) { + wiki.CSV(msg.Message, msg.Result(), kit.Split(m.Config(mdb.FIELD))...).Tables(func(value ice.Maps) { if m.FieldsIsDetail() { m.Push(mdb.DETAIL, value, kit.Split(m.Config(mdb.FIELD))) m.Push(mdb.TIME, m.Time()) diff --git a/misc/bash/favor.go b/misc/bash/favor.go index 465d584e..284db8f8 100644 --- a/misc/bash/favor.go +++ b/misc/bash/favor.go @@ -3,6 +3,7 @@ package bash import ( ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/cli" + "shylinux.com/x/icebergs/base/ctx" "shylinux.com/x/icebergs/base/mdb" kit "shylinux.com/x/toolkits" ) @@ -27,8 +28,8 @@ func init() { mdb.INSERT: {Name: "insert zone=系统命令 type=shell name=1 text=pwd pwd=/home", Help: "添加"}, cli.SYSTEM: {Name: "system", Help: "命令", Hand: func(m *ice.Message, arg ...string) { m.Option(cli.CMD_DIR, m.Option(cli.PWD)) - m.ProcessCommand(cli.SYSTEM, kit.Split(m.Option(mdb.TEXT)), arg...) - m.ProcessCommandOpt(arg, cli.PWD) + ctx.ProcessCommand(m, cli.SYSTEM, kit.Split(m.Option(mdb.TEXT)), arg...) + ctx.ProcessCommandOpt(m, arg, cli.PWD) }}, }, mdb.ZoneAction(mdb.SHORT, mdb.ZONE, mdb.FIELD, "time,id,type,name,text,pwd,username,hostname")), Hand: func(m *ice.Message, arg ...string) { if mdb.ZoneSelect(m, arg...); len(arg) == 0 { diff --git a/misc/bash/input.go b/misc/bash/input.go index 3b7bf344..55dae5f9 100644 --- a/misc/bash/input.go +++ b/misc/bash/input.go @@ -2,6 +2,7 @@ package bash import ( ice "shylinux.com/x/icebergs" + "shylinux.com/x/icebergs/base/mdb" kit "shylinux.com/x/toolkits" "strings" @@ -35,7 +36,7 @@ func init() { line := []rune(m.Option("line")) if begin := kit.Int(m.Option("point")); begin < len(line) { - m.Richs("login", nil, m.Option("sid"), func(key string, value ice.Map) { + mdb.Richs(m, "login", nil, m.Option("sid"), func(key string, value ice.Map) { m.Echo(string(line[:begin])) for i := begin; i < len(line); i++ { if i-begin < 3 && i < len(line)-1 { @@ -60,7 +61,7 @@ func init() { } fallthrough case "end": - m.Richs("login", nil, m.Option("sid"), func(key string, value ice.Map) { + mdb.Richs(m, "login", nil, m.Option("sid"), func(key string, value ice.Map) { last_text := kit.Format(kit.Value(value, "last.text")) last_list := kit.Simple(kit.Value(value, "last.list")) last_index := kit.Int(kit.Value(value, "last.index")) diff --git a/misc/bash/run.go b/misc/bash/run.go index f5656501..5bdc3077 100644 --- a/misc/bash/run.go +++ b/misc/bash/run.go @@ -5,6 +5,7 @@ import ( "strings" ice "shylinux.com/x/icebergs" + "shylinux.com/x/icebergs/base/aaa" "shylinux.com/x/icebergs/base/ctx" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" @@ -86,7 +87,7 @@ func init() { }) }}, ice.RUN: {Name: "run", Help: "执行", Hand: func(m *ice.Message, arg ...string) { - if m.Right(arg) && !m.PodCmd(arg) { + if aaa.Right(m, arg) && !ctx.PodCmd(m, arg) { m.Cmdy(arg) } if m.Result() == "" { diff --git a/misc/bash/sync.go b/misc/bash/sync.go index b9e544ad..cc5418db 100644 --- a/misc/bash/sync.go +++ b/misc/bash/sync.go @@ -6,6 +6,7 @@ import ( ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/aaa" "shylinux.com/x/icebergs/base/cli" + "shylinux.com/x/icebergs/base/ctx" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/tcp" kit "shylinux.com/x/toolkits" @@ -28,8 +29,8 @@ func init() { SYNC: {Name: "sync id auto page export import", Help: "同步流", Actions: ice.MergeAction(ice.Actions{ cli.SYSTEM: {Name: "system", Help: "命令", Hand: func(m *ice.Message, arg ...string) { m.Option(cli.CMD_DIR, m.Option(cli.PWD)) - m.ProcessCommand(cli.SYSTEM, kit.Split(m.Option(mdb.TEXT)), arg...) - m.ProcessCommandOpt(arg, cli.PWD) + ctx.ProcessCommand(m, cli.SYSTEM, kit.Split(m.Option(mdb.TEXT)), arg...) + ctx.ProcessCommandOpt(m, arg, cli.PWD) }}, mdb.INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) { m.Cmdy(FAVOR, mdb.INPUTS, arg) @@ -38,7 +39,7 @@ func init() { m.Cmdy(FAVOR, mdb.INSERT) }}, }, mdb.ListAction(mdb.FIELD, "time,id,type,name,text,pwd,username,hostname")), Hand: func(m *ice.Message, arg ...string) { - m.OptionPage(kit.Slice(arg, 1)...) + mdb.OptionPage(m, kit.Slice(arg, 1)...) mdb.ListSelect(m, kit.Slice(arg, 0, 1)...) m.PushAction(cli.SYSTEM, FAVOR) m.StatusTimeCountTotal(m.Config(mdb.COUNT)) diff --git a/misc/bash/trash.go b/misc/bash/trash.go index 69791227..14417ec0 100644 --- a/misc/bash/trash.go +++ b/misc/bash/trash.go @@ -6,6 +6,7 @@ import ( ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/aaa" "shylinux.com/x/icebergs/base/cli" + "shylinux.com/x/icebergs/base/ctx" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" "shylinux.com/x/icebergs/base/tcp" @@ -39,13 +40,13 @@ func init() { mdb.PRUNES: {Name: "prunes before@date", Help: "清理", Hand: func(m *ice.Message, arg ...string) { mdb.HashPrunes(m, func(value ice.Maps) bool { os.RemoveAll(value[TO]) - return false + return true }) }}, nfs.CAT: {Name: "cat", Help: "查看", Hand: func(m *ice.Message, arg ...string) { m.Option(nfs.DIR_ROOT, m.Option(TO)) - m.ProcessCommand(nfs.CAT, []string{}, arg...) - m.ProcessCommandOpt(arg, TO) + ctx.ProcessCommand(m, nfs.CAT, []string{}, arg...) + ctx.ProcessCommandOpt(m, arg, TO) }}, }, mdb.HashAction(mdb.FIELD, "time,hash,username,hostname,size,from,to")), Hand: func(m *ice.Message, arg ...string) { mdb.HashSelect(m, arg...) diff --git a/misc/chrome/cache.go b/misc/chrome/cache.go index 13db7d48..c00f78ba 100644 --- a/misc/chrome/cache.go +++ b/misc/chrome/cache.go @@ -30,7 +30,7 @@ func (c cache) Create(m *ice.Message, arg ...string) *ice.Message { c.Hash.Modify(m, kit.Simple(mdb.COUNT, count, mdb.TOTAL, total, mdb.VALUE, kit.Format(value))...) }) m.Cmdy(nfs.LINK, path.Join(m.Config(nfs.PATH), m.Option(mdb.NAME)), msg.Append(nfs.FILE)) - m.ToastSuccess() + web.ToastSuccess(m.Message) return m } func (c cache) Prunes(m *ice.Message, arg ...string) { diff --git a/misc/chrome/sync.go b/misc/chrome/sync.go index b8fcf4c6..faed15b0 100644 --- a/misc/chrome/sync.go +++ b/misc/chrome/sync.go @@ -3,6 +3,7 @@ package chrome import ( "shylinux.com/x/ice" "shylinux.com/x/icebergs/base/mdb" + "shylinux.com/x/icebergs/base/web" ) type sync struct { @@ -27,7 +28,7 @@ func (s sync) Insert(m *ice.Message, arg ...string) { } func (s sync) Favor(m *ice.Message, arg ...string) { m.Cmdy(s.favor.Insert, m.OptionSimple("zone,type,name,link")) - m.ToastSuccess() + web.ToastSuccess(m.Message) } func (s sync) List(m *ice.Message, arg ...string) { s.Lists.List(m, arg...) diff --git a/misc/chrome/video.go b/misc/chrome/video.go index 41072597..8e0b32fb 100644 --- a/misc/chrome/video.go +++ b/misc/chrome/video.go @@ -2,6 +2,7 @@ package chrome import ( "shylinux.com/x/ice" + "shylinux.com/x/icebergs/base/ctx" ) type video struct { @@ -13,7 +14,7 @@ type video struct { } func (v video) List(m *ice.Message, arg ...string) { - m.DisplayStory("video.js") + ctx.DisplayStory(m.Message, "video.js") m.Echo("hello world") } diff --git a/misc/git/git.go b/misc/git/git.go index 713ca891..2b68d5da 100644 --- a/misc/git/git.go +++ b/misc/git/git.go @@ -18,7 +18,7 @@ var Index = &ice.Context{Name: GIT, Help: "代码库", Configs: ice.Configs{ }, Commands: ice.Commands{ GIT: {Name: "git path auto install order build download", Help: "代码库", Actions: ice.MergeAction(ice.Actions{ code.INSTALL: {Name: "install", Help: "安装", Hand: func(m *ice.Message, arg ...string) { - cli.PushStream(m) + web.PushStream(m) defer m.ProcessInner() m.Cmdy(cli.SYSTEM, "yum", "install", "-y", "git") diff --git a/misc/git/repos.go b/misc/git/repos.go index 64e77fff..5856b71f 100644 --- a/misc/git/repos.go +++ b/misc/git/repos.go @@ -25,7 +25,7 @@ func _repos_path(name string) string { func _repos_insert(m *ice.Message, name string, dir string) { if s, e := os.Stat(m.Option(cli.CMD_DIR, path.Join(dir, ".git"))); e == nil && s.IsDir() { ls := strings.SplitN(strings.Trim(m.Cmdx(cli.SYSTEM, GIT, "log", "-n1", `--pretty=format:"%ad %s"`, "--date=iso"), `"`), ice.SP, 4) - m.Rich(REPOS, nil, kit.Data(mdb.NAME, name, nfs.PATH, dir, + mdb.Rich(m, REPOS, nil, kit.Data(mdb.NAME, name, nfs.PATH, dir, COMMIT, kit.Select("", ls, 3), mdb.TIME, strings.Join(ls[:2], ice.SP), BRANCH, strings.TrimSpace(m.Cmdx(cli.SYSTEM, GIT, BRANCH)), REMOTE, strings.TrimSpace(m.Cmdx(cli.SYSTEM, GIT, REMOTE, "-v")), diff --git a/misc/git/server.go b/misc/git/server.go index 7b0b2a3b..b3555266 100644 --- a/misc/git/server.go +++ b/misc/git/server.go @@ -140,12 +140,12 @@ func init() { }}, }, ctx.CmdAction()), Hand: func(m *ice.Message, arg ...string) { if !m.IsCliUA() { - p := kit.Split(m.MergeURL2("/x/"+path.Join(arg...)), "?")[0] + p := kit.Split(web.MergeURL2(m, "/x/"+path.Join(arg...)), "?")[0] m.RenderResult("git clone %v", p) return } if m.Option("go-get") == "1" { // 下载地址 - p := kit.Split(m.MergeURL2("/x/"+path.Join(arg...)), "?")[0] + p := kit.Split(web.MergeURL2(m, "/x/"+path.Join(arg...)), "?")[0] m.RenderResult(kit.Format(``, "go-import", kit.Format(`%s git %s`, strings.TrimPrefix(p, "https://"), p))) return } @@ -153,27 +153,27 @@ func init() { switch repos, service := _server_param(m, arg...); service { case "receive-pack": // 上传代码 if err := _server_login(m); err != nil { - web.RenderHeader(m, "WWW-Authenticate", `Basic realm="git server"`) - web.RenderStatus(m, 401, err.Error()) + web.RenderHeader(m.W, "WWW-Authenticate", `Basic realm="git server"`) + web.RenderStatus(m.W, 401, err.Error()) return // 没有权限 } if !kit.FileExists(path.Join(repos)) { m.Cmd(cli.SYSTEM, GIT, INIT, "--bare", repos) // 创建仓库 - m.Log_CREATE(REPOS, repos) + m.Logs(mdb.CREATE, REPOS, repos) } case "upload-pack": // 下载代码 aaa.UserRoot(m) if kit.Select("", arg, 1) == "info" && m.Cmd(web.DREAM, arg[0]).Length() > 0 { - m.Cmd(web.SPACE, arg[0], "web.code.git.status", "submit", m.MergeURL2("/x/")+arg[0]) + m.Cmd(web.SPACE, arg[0], "web.code.git.status", "submit", web.MergeURL2(m, "/x/")+arg[0]) } if !kit.FileExists(path.Join(repos)) { - web.RenderStatus(m, 404, kit.Format("not found: %s", arg[0])) + web.RenderStatus(m.W, 404, kit.Format("not found: %s", arg[0])) return } } if err := _server_repos(m, arg...); err != nil { - web.RenderStatus(m, 500, err.Error()) + web.RenderStatus(m.W, 500, err.Error()) } }}, SERVER: {Name: "server path auto create import", Help: "服务器", Actions: ice.Actions{ @@ -183,7 +183,7 @@ func init() { }}, mdb.IMPORT: {Name: "import", Help: "导入", Hand: func(m *ice.Message, arg ...string) { m.Cmdy(REPOS, ice.OptionFields("time,name,path")).Tables(func(value ice.Maps) { - remote := strings.Split(m.MergeURL2("/x/"+value[REPOS]), "?")[0] + remote := strings.Split(web.MergeURL2(m, "/x/"+value[REPOS]), "?")[0] m.Option(cli.CMD_DIR, value[nfs.PATH]) m.Cmd(cli.SYSTEM, GIT, PUSH, remote, MASTER) m.Cmd(cli.SYSTEM, GIT, PUSH, "--tags", remote, MASTER) @@ -196,7 +196,7 @@ func init() { }, Hand: func(m *ice.Message, arg ...string) { if m.Option(nfs.DIR_ROOT, ice.USR_LOCAL_REPOS); len(arg) == 0 { m.Cmdy(nfs.DIR, nfs.PWD).Tables(func(value ice.Maps) { - m.PushScript("git clone " + m.MergeLink("/x/"+strings.TrimSuffix(value[nfs.PATH], ice.PS))) + m.PushScript("git clone " + web.MergeURL2(m, "/x/"+strings.TrimSuffix(value[nfs.PATH], ice.PS))) }) m.Cut("time,path,size,script,action") m.StatusTimeCount() diff --git a/misc/git/spide.go b/misc/git/spide.go index 4d20113c..fb0b0eed 100644 --- a/misc/git/spide.go +++ b/misc/git/spide.go @@ -112,7 +112,7 @@ func init() { } else { m.Option(nfs.DIR_ROOT, path.Join(ice.USR, arg[0])+ice.PS) } - m.DisplayStory("spide.js?field=path", "root", arg[0]) + ctx.DisplayStory(m, "spide.js?field=path", "root", arg[0]) if len(arg) == 1 { // 目录列表 m.Option(nfs.DIR_DEEP, ice.TRUE) diff --git a/misc/git/status.go b/misc/git/status.go index d774aebc..aa56ed13 100644 --- a/misc/git/status.go +++ b/misc/git/status.go @@ -10,6 +10,7 @@ import ( "shylinux.com/x/icebergs/base/ctx" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" + "shylinux.com/x/icebergs/base/web" "shylinux.com/x/icebergs/core/code" kit "shylinux.com/x/toolkits" ) @@ -36,10 +37,10 @@ func _status_tags(m *ice.Message, repos string) { } }) - m.GoToast(TAGS, func(toast func(string, int, int)) { + web.GoToast(m, TAGS, func(toast func(string, int, int)) { count, total := 0, len(vs) toast(cli.BEGIN, count, total) - defer m.PushRefresh() + defer web.PushNoticeRefresh(m) for k := range vs { if k != repos && repos != "" { @@ -87,7 +88,7 @@ func _status_tags(m *ice.Message, repos string) { }) } func _status_each(m *ice.Message, title string, cmds ...string) { - m.GoToast(title, func(toast func(string, int, int)) { + web.GoToast(m, title, func(toast func(string, int, int)) { count, total := 0, len(m.Confm(REPOS, mdb.HASH)) toast(cli.BEGIN, count, total) @@ -96,7 +97,7 @@ func _status_each(m *ice.Message, title string, cmds ...string) { toast(value[REPOS], count, total) if msg := m.Cmd(cmds, ice.Option{cli.CMD_DIR, value[nfs.PATH]}); !cli.IsSuccess(msg) { - m.Toast3s(msg.Append(cli.CMD_ERR), "error: "+value[REPOS]) + web.Toast3s(m, msg.Append(cli.CMD_ERR), "error: "+value[REPOS]) list = append(list, value[REPOS]) m.Sleep3s() } @@ -104,11 +105,11 @@ func _status_each(m *ice.Message, title string, cmds ...string) { }) if len(list) > 0 { - m.Toast30s(strings.Join(list, ice.NL), ice.FAILURE) + web.Toast30s(m, strings.Join(list, ice.NL), ice.FAILURE) } else { toast(ice.SUCCESS, count, total) } - m.PushRefresh() + web.PushNoticeRefresh(m) }) } func _status_stat(m *ice.Message, files, adds, dels int) (int, int, int) { @@ -236,9 +237,9 @@ func init() { m.ProcessHold() }}, MAKE: {Name: "make", Help: "编译", Hand: func(m *ice.Message, arg ...string) { - cli.PushStream(m) + web.PushStream(m) m.Cmdy(cli.SYSTEM, MAKE) - m.ToastSuccess() + web.ToastSuccess(m) m.ProcessHold() }}, PUSH: {Name: "push", Help: "上传", Hand: func(m *ice.Message, arg ...string) { @@ -322,7 +323,7 @@ func init() { files, adds, dels, last := _status_list(m) m.Status("files", files, "adds", adds, "dels", dels, "last", last.Format(ice.MOD_TIME)) - m.Toast3s(kit.Format("files: %d, adds: %d, dels: %d", files, adds, dels), ice.CONTEXTS) + web.Toast3s(m, kit.Format("files: %d, adds: %d, dels: %d", files, adds, dels), ice.CONTEXTS) return } @@ -332,7 +333,7 @@ func init() { files, adds, dels := _status_stat(m, 0, 0, 0) m.Status("files", files, "adds", adds, "dels", dels) - m.Toast3s(kit.Format("files: %d, adds: %d, dels: %d", files, adds, dels), arg[0]) + web.Toast3s(m, kit.Format("files: %d, adds: %d, dels: %d", files, adds, dels), arg[0]) }}, }) } diff --git a/misc/git/total.go b/misc/git/total.go index 9472b040..cd20200c 100644 --- a/misc/git/total.go +++ b/misc/git/total.go @@ -51,7 +51,7 @@ func init() { // 提交统计 days, commit, adds, dels, rest := 0, 0, 0, 0, 0 - m.Richs(REPOS, nil, mdb.FOREACH, func(mu *sync.Mutex, key string, value ice.Map) { + Richs(m, REPOS, nil, mdb.FOREACH, func(mu *sync.Mutex, key string, value ice.Map) { value = kit.GetMeta(value) if m.Config(kit.Keys("skip", value[mdb.NAME])) == ice.TRUE { return @@ -166,3 +166,19 @@ func init() { }}, }}) } + +func Richs(m *ice.Message, prefix string, chain ice.Any, raw ice.Any, cb func(*sync.Mutex, string, ice.Map)) { + wg, mu := &sync.WaitGroup{}, &sync.Mutex{} + defer wg.Wait() + mdb.Richs(m, prefix, chain, raw, func(key string, value ice.Map) { + wg.Add(1) + val := ice.Map{} + for k, v := range value { + val[k] = v + } + m.Go(func() { + defer wg.Done() + cb(mu, key, val) + }) + }) +} diff --git a/misc/input/input.go b/misc/input/input.go index d30979d3..050a45e8 100644 --- a/misc/input/input.go +++ b/misc/input/input.go @@ -41,7 +41,7 @@ func (i input) Load(m *ice.Message, arg ...string) { lib := kit.Select(path.Base(m.Option(nfs.FILE)), m.Option(mdb.ZONE)) m.Assert(os.RemoveAll(path.Join(m.Config(mdb.STORE), lib))) m.Cmd(mdb.DELETE, m.PrefixKey(), "", mdb.HASH, mdb.ZONE, lib) - prefix := kit.Keys(mdb.HASH, m.Rich(m.PrefixKey(), "", kit.Data( + prefix := kit.Keys(mdb.HASH, mdb.Rich(m.Message, m.PrefixKey(), "", kit.Data( mdb.STORE, path.Join(m.Config(mdb.STORE), lib), m.ConfigSimple(mdb.FSIZE, mdb.LIMIT, mdb.LEAST), mdb.ZONE, lib, mdb.COUNT, 0, @@ -56,14 +56,14 @@ func (i input) Load(m *ice.Message, arg ...string) { if len(line) < 2 || (len(line) > 2 && line[2] == "0") { continue } - m.Grow(m.PrefixKey(), prefix, kit.Dict(TEXT, line[0], CODE, line[1], WEIGHT, kit.Select("999999", line, 2))) + mdb.Grow(m.Message, m.PrefixKey(), prefix, kit.Dict(TEXT, line[0], CODE, line[1], WEIGHT, kit.Select("999999", line, 2))) } // 保存词库 m.Conf(m.PrefixKey(), kit.Keys(prefix, kit.Keym(mdb.LIMIT)), 0) m.Conf(m.PrefixKey(), kit.Keys(prefix, kit.Keym(mdb.LEAST)), 0) - n := m.Grow(m.PrefixKey(), prefix, kit.Dict(TEXT, "成功", CODE, "z", WEIGHT, "0")) - m.Log_IMPORT(m.PrefixKey(), lib, mdb.COUNT, n) + n := mdb.Grow(m.Message, m.PrefixKey(), prefix, kit.Dict(TEXT, "成功", CODE, "z", WEIGHT, "0")) + m.Logs(mdb.IMPORT, m.PrefixKey(), lib, mdb.COUNT, n) m.Echo("%s: %d", lib, n) } } @@ -73,8 +73,8 @@ func (i input) Save(m *ice.Message, arg ...string) { n := 0 m.Option(ice.CACHE_LIMIT, -2) for _, lib := range kit.Split(m.Option(mdb.ZONE)) { - m.Richs(m.PrefixKey(), "", lib, func(key string, value ice.Map) { - m.Grows(m.PrefixKey(), kit.Keys(mdb.HASH, key), "", "", func(index int, value ice.Map) { + mdb.Richs(m.Message, m.PrefixKey(), "", lib, func(key string, value ice.Map) { + mdb.Grows(m.Message, m.PrefixKey(), kit.Keys(mdb.HASH, key), "", "", func(index int, value ice.Map) { if value[CODE] != "z" { fmt.Fprintf(f, "%s %s %s\n", value[TEXT], value[CODE], value[WEIGHT]) n++ @@ -82,7 +82,7 @@ func (i input) Save(m *ice.Message, arg ...string) { }) }) } - m.Log_EXPORT(nfs.FILE, p, mdb.COUNT, n) + m.Logs(mdb.EXPORT, nfs.FILE, p, mdb.COUNT, n) m.Echo("%s: %d", p, n) } } diff --git a/misc/lark/sso.go b/misc/lark/sso.go index 84156115..c0eb371f 100644 --- a/misc/lark/sso.go +++ b/misc/lark/sso.go @@ -15,12 +15,12 @@ func init() { Index.MergeCommands(ice.Commands{ "/sso": {Name: "/sso", Help: "网页", Hand: func(m *ice.Message, arg ...string) { if m.Option(ice.MSG_USERNAME) != "" { // 默认主页 - m.RenderIndex(web.SERVE, ice.VOLCANOS) + web.RenderIndex(m, web.SERVE, ice.VOLCANOS) return } appid := m.Cmd(APP).Append(APPID) - home := m.MergeURL2("/chat/lark/sso") + home := web.MergeURL2(m, "/chat/lark/sso") if m.Option(cli.CODE) == "" { // 登录页面 if back := m.R.Header.Get("Referer"); back != "" { home = kit.MergeURL(home, cli.BACK, back) diff --git a/misc/lark/talk.go b/misc/lark/talk.go index d99e7a5b..4213cedb 100644 --- a/misc/lark/talk.go +++ b/misc/lark/talk.go @@ -16,8 +16,8 @@ func init() { Index.MergeCommands(ice.Commands{ TALK: {Name: "talk text", Help: "聊天", Hand: func(m *ice.Message, arg ...string) { cmds := kit.Split(strings.Join(arg, " ")) - if aaa.UserLogin(m, m.Option(OPEN_ID), ""); !m.Right(cmds) { - if aaa.UserLogin(m, m.Option(OPEN_CHAT_ID), ""); !m.Right(cmds) { + if aaa.UserLogin(m, m.Option(OPEN_ID), ""); !aaa.Right(m, cmds) { + if aaa.UserLogin(m, m.Option(OPEN_CHAT_ID), ""); !aaa.Right(m, cmds) { m.Cmd(DUTY, m.Option(OPEN_CHAT_ID), m.Option("text_without_at_bot")) m.Cmd(HOME) return // 没有权限 diff --git a/misc/tmux/buffer.go b/misc/tmux/buffer.go index 61c7df22..379c4af9 100644 --- a/misc/tmux/buffer.go +++ b/misc/tmux/buffer.go @@ -29,7 +29,7 @@ func init() { m.Config(mdb.COUNT, "0") m.Cmd(BUFFER).Table(func(index int, value ice.Maps, head []string) { - m.Grow(m.PrefixKey(), "", kit.Dict( + mdb.Grow(m, m.PrefixKey(), "", kit.Dict( mdb.NAME, value[head[0]], mdb.TEXT, m.Cmdx(cli.SYSTEM, TMUX, "show-buffer", "-b", value[head[0]]), )) }) @@ -39,9 +39,9 @@ func init() { m.Config(mdb.LIST, "") m.Config(mdb.COUNT, "0") - m.Option(ice.CACHE_LIMIT, "-1") + m.Option(mdb.CACHE_LIMIT, "-1") m.Cmdy(mdb.IMPORT, m.PrefixKey(), "", mdb.LIST) - m.Grows(m.PrefixKey(), "", "", "", func(index int, value ice.Map) { + mdb.Grows(m, m.PrefixKey(), "", "", "", func(index int, value ice.Map) { m.Cmd(cli.SYSTEM, TMUX, "set-buffer", "-b", value[mdb.NAME], value[mdb.TEXT]) }) }}, diff --git a/misc/vim/favor.go b/misc/vim/favor.go index c12c4c5b..9c568536 100644 --- a/misc/vim/favor.go +++ b/misc/vim/favor.go @@ -5,6 +5,7 @@ import ( ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/cli" + "shylinux.com/x/icebergs/base/ctx" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" "shylinux.com/x/icebergs/core/code" @@ -33,7 +34,7 @@ func init() { mdb.INSERT: {Name: "insert zone=数据结构 type name=hi text=hello file line", Help: "添加"}, code.INNER: {Name: "inner", Help: "源码", Hand: func(m *ice.Message, arg ...string) { p := path.Join(m.Option(cli.PWD), m.Option(nfs.FILE)) - m.ProcessCommand(code.INNER, []string{path.Dir(p) + ice.PS, path.Base(p), m.Option(nfs.LINE)}, arg...) + ctx.ProcessCommand(m, code.INNER, []string{path.Dir(p) + ice.PS, path.Base(p), m.Option(nfs.LINE)}, arg...) }}, }, mdb.ZoneAction( mdb.SHORT, mdb.ZONE, mdb.FIELD, "time,id,type,name,text,file,line,pwd", diff --git a/misc/vim/sync.go b/misc/vim/sync.go index 67c2736d..7c5d4b86 100644 --- a/misc/vim/sync.go +++ b/misc/vim/sync.go @@ -6,6 +6,7 @@ import ( ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/aaa" "shylinux.com/x/icebergs/base/cli" + "shylinux.com/x/icebergs/base/ctx" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" "shylinux.com/x/icebergs/core/code" @@ -28,7 +29,7 @@ func init() { SYNC: {Name: "sync id auto page export import", Help: "同步流", Actions: ice.MergeAction(ice.Actions{ code.INNER: {Name: "inner", Help: "源码", Hand: func(m *ice.Message, arg ...string) { p := path.Join(m.Option(cli.PWD), m.Option(BUF)) - m.ProcessCommand(code.INNER, []string{path.Dir(p) + ice.PS, path.Base(p), m.Option(ROW)}, arg...) + ctx.ProcessCommand(m, code.INNER, []string{path.Dir(p) + ice.PS, path.Base(p), m.Option(ROW)}, arg...) }}, mdb.INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) { m.Cmdy(FAVOR, mdb.INPUTS, arg) @@ -38,7 +39,7 @@ func init() { nfs.FILE, m.Option(BUF), nfs.LINE, m.Option(ROW)) }}, }, mdb.ListAction(mdb.FIELD, "time,id,type,name,text,pwd,buf,row,col")), Hand: func(m *ice.Message, arg ...string) { - m.OptionPage(kit.Slice(arg, 1)...) + mdb.OptionPage(m, kit.Slice(arg, 1)...) mdb.ListSelect(m, kit.Slice(arg, 0, 1)...) m.PushAction(code.INNER, FAVOR) m.StatusTimeCountTotal(m.Config(mdb.COUNT)) diff --git a/misc/vim/tags.go b/misc/vim/tags.go index 9ceca274..a3d81fb9 100644 --- a/misc/vim/tags.go +++ b/misc/vim/tags.go @@ -5,6 +5,7 @@ import ( "strings" ice "shylinux.com/x/icebergs" + "shylinux.com/x/icebergs/base/ctx" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" "shylinux.com/x/icebergs/core/code" @@ -53,7 +54,7 @@ func init() { }}, mdb.INSERT: {Name: "insert zone=core type name=hi text=hello path file line", Help: "添加"}, code.INNER: {Name: "inner", Help: "源码", Hand: func(m *ice.Message, arg ...string) { - m.ProcessCommand(code.INNER, m.OptionSplit("path,file,line"), arg...) + ctx.ProcessCommand(m, code.INNER, m.OptionSplit("path,file,line"), arg...) }}, INPUT: {Name: "input name text", Help: "补全", Hand: func(m *ice.Message, arg ...string) { if m.Option(mdb.TEXT) == "" { diff --git a/misc/wx/login.go b/misc/wx/login.go index 1feacb36..d909823e 100644 --- a/misc/wx/login.go +++ b/misc/wx/login.go @@ -91,7 +91,7 @@ func init() { m.Cmdy(chat.SCAN, mdb.CREATE, mdb.TYPE, wiki.IMAGE, mdb.NAME, m.Option("Title"), mdb.TEXT, m.Option("URL")) case TEXT: // 文本 - if cmds := kit.Split(m.Option("Content")); m.Right(cmds) { + if cmds := kit.Split(m.Option("Content")); aaa.Right(m, cmds) { m.Cmdy(TEXT, cmds) break } diff --git a/option.go b/option.go index 5dde2ba5..3950b598 100644 --- a/option.go +++ b/option.go @@ -1,9 +1,6 @@ package ice import ( - "encoding/json" - "net/url" - "os" "path" "strings" "time" @@ -17,58 +14,18 @@ type Option struct { } func OptionFields(arg ...string) Option { return Option{MSG_FIELDS, kit.Join(arg)} } - -func (m *Message) OptionCB(key string, cb ...Any) Any { - if len(cb) > 0 { - return m.Optionv(kit.Keycb(key), cb...) - } - return m.Optionv(kit.Keycb(key)) -} func (m *Message) OptionFields(arg ...string) string { if len(arg) > 0 { m.Option(MSG_FIELDS, kit.Join(arg)) } return kit.Join(kit.Simple(m.Optionv(MSG_FIELDS))) } -func (m *Message) OptionPages(arg ...string) (page int, size int) { - m.Option(CACHE_LIMIT, kit.Select("", arg, 0)) - m.Option(CACHE_OFFEND, kit.Select("", arg, 1)) - m.Option(CACHE_FILTER, kit.Select("", arg, 2)) - m.Option("limit", kit.Select(m.Option("limit"), arg, 0)) - m.Option("offend", kit.Select(m.Option("offend"), arg, 1)) - size = kit.Int(kit.Select("10", m.Option("limit"))) - page = kit.Int(m.Option("offend"))/size + 1 - return -} -func (m *Message) OptionPage(arg ...string) int { - page, _ := m.OptionPages(arg...) - return page -} -func (m *Message) OptionLoad(file string) *Message { - if f, e := os.Open(file); e == nil { - defer f.Close() - - var data Any - m.Assert(json.NewDecoder(f).Decode(&data)) - - kit.Fetch(data, func(key string, value Any) { - m.Option(key, kit.Simple(value)) - }) - } - return m -} func (m *Message) OptionDefault(key, value string) string { if m.Option(key) == "" { m.Option(key, value) } return m.Option(key) } -func (m *Message) OptionSplit(key ...string) (res []string) { - for _, k := range kit.Split(kit.Join(key)) { - res = append(res, m.Option(k)) - } - return res -} func (m *Message) OptionSimple(key ...string) (res []string) { for _, k := range kit.Split(kit.Join(key)) { if k == "" || m.Option(k) == "" { @@ -78,53 +35,30 @@ func (m *Message) OptionSimple(key ...string) (res []string) { } return } -func (m *Message) OptionTemplate() string { - res := []string{`class="story"`} - for _, key := range kit.Split(STYLE) { - if m.Option(key) != "" { - res = append(res, kit.Format(`s="%s"`, key, m.Option(key))) - } +func (m *Message) OptionSplit(key ...string) (res []string) { + for _, k := range kit.Split(kit.Join(key)) { + res = append(res, m.Option(k)) } - for _, key := range kit.Split("type,name,text") { - if key == TEXT && m.Option(TYPE) == "spark" { - continue - } - if m.Option(key) != "" { - res = append(res, kit.Format(`data-%s="%s"`, key, m.Option(key))) - } + return res +} +func (m *Message) OptionCB(key string, cb ...Any) Any { + if len(cb) > 0 { + return m.Optionv(kit.Keycb(kit.Select(m.CommandKey(), key)), cb...) } - kit.Fetch(m.Optionv("extra"), func(key string, value string) { - if value != "" { - res = append(res, kit.Format(`data-%s="%s"`, key, value)) - } - }) - return kit.Join(res, SP) + return m.Optionv(kit.Keycb(kit.Select(m.CommandKey(), key))) } func (m *Message) FieldsIsDetail() bool { if len(m.meta[MSG_APPEND]) == 2 && m.meta[MSG_APPEND][0] == KEY && m.meta[MSG_APPEND][1] == VALUE { return true } - if m.OptionFields() == CACHE_DETAIL { + if m.OptionFields() == FIELDS_DETAIL { return true } return false } func (m *Message) Fields(length int, fields ...string) string { - return m.Option(MSG_FIELDS, kit.Select(kit.Select(CACHE_DETAIL, fields, length), m.Option(MSG_FIELDS))) -} -func (m *Message) Upload(dir string) { - up := kit.Simple(m.Optionv(MSG_UPLOAD)) - if len(up) < 2 { - msg := m.Cmd(CACHE, "upload") - up = kit.Simple(msg.Append(HASH), msg.Append(NAME), msg.Append("size")) - } - - if p := path.Join(dir, up[1]); m.Option(MSG_USERPOD) == "" { - m.Cmdy(CACHE, "watch", up[0], p) // 本机文件 - } else { // 下发文件 - m.Cmdy(SPIDE, DEV, SAVE, p, "GET", m.MergeURL2(path.Join("/share/cache", up[0]))) - } + return m.Option(MSG_FIELDS, kit.Select(kit.Select(FIELDS_DETAIL, fields, length), m.Option(MSG_FIELDS))) } func (m *Message) Action(arg ...Any) *Message { for i, v := range arg { @@ -157,71 +91,6 @@ func (m *Message) StatusTimeCountTotal(arg ...Any) { m.Status(TIME, m.Time(), kit.MDB_COUNT, kit.Split(m.FormatSize())[0], kit.MDB_TOTAL, arg, kit.MDB_COST, m.FormatCost()) } -func (m *Message) ToastProcess(arg ...Any) func() { - if len(arg) == 0 { - arg = kit.List("", "-1") - } - if len(arg) == 1 { - arg = append(arg, "-1") - } - m.Toast(PROCESS, arg...) - return func() { m.Toast(SUCCESS) } -} -func (m *Message) ToastRestart(arg ...Any) { m.Toast(RESTART, arg...) } -func (m *Message) ToastFailure(arg ...Any) { m.Toast(FAILURE, arg...) } -func (m *Message) ToastSuccess(arg ...Any) { m.Toast(SUCCESS, arg...) } -func (m *Message) Toast(text string, arg ...Any) { // [title [duration [progress]]] - if len(arg) > 1 { - switch val := arg[1].(type) { - case string: - if value, err := time.ParseDuration(val); err == nil { - arg[1] = int(value / time.Millisecond) - } - } - } - - m.PushNoticeToast("", text, arg) -} -func (m *Message) PushNotice(arg ...Any) { - m.Optionv(MSG_OPTS, m.meta[MSG_OPTION]) - if m.Option(MSG_USERPOD) == "" { - m.Cmd(SPACE, m.Option(MSG_DAEMON), arg) - } else { - opts := kit.Dict(POD, m.Option(MSG_DAEMON), "cmds", kit.Simple(arg...)) - for _, k := range m.meta[MSG_OPTS] { - opts[k] = m.Option(k) - } - m.Cmd("web.spide", OPS, m.MergeURL2("/share/toast/"), kit.Format(opts)) - } -} -func (m *Message) PushNoticeGrow(arg ...Any) { - m.PushNotice(kit.List("grow", arg)...) -} -func (m *Message) PushNoticeToast(arg ...Any) { - m.PushNotice(kit.List("toast", arg)...) -} -func (m *Message) PushRefresh(arg ...Any) { - m.PushNotice(kit.List("refresh")...) -} -func (m *Message) Toast3s(text string, arg ...Any) { - m.Toast(text, kit.List(kit.Select("", arg, 0), kit.Select("3s", arg, 1))...) -} -func (m *Message) Toast30s(text string, arg ...Any) { - m.Toast(text, kit.List(kit.Select("", arg, 0), kit.Select("30s", arg, 1))...) -} -func (m *Message) GoToast(title string, cb func(toast func(string, int, int))) { - m.Go(func() { - cb(func(name string, count, total int) { - m.Toast( - kit.Format("%s %s/%s", name, strings.TrimSuffix(kit.FmtSize(int64(count)), "B"), strings.TrimSuffix(kit.FmtSize(int64(total)), "B")), - kit.Format("%s %d%%", title, count*100/total), - kit.Select("3000", "30000", count < total), - count*100/total, - ) - }) - }) -} - func (m *Message) Process(action string, arg ...Any) { m.Option(MSG_PROCESS, action) m.Option(PROCESS_ARG, arg...) @@ -256,58 +125,56 @@ func (m *Message) ProcessDisplay(arg ...Any) { m.Option(MSG_DISPLAY, arg...) } -func (m *Message) ProcessCommand(cmd string, val []string, arg ...string) { - if len(arg) > 0 && arg[0] == RUN { - m.Cmdy(cmd, arg[1:]) - return - } - - m.Cmdy(COMMAND, cmd) - m.ProcessField(cmd, RUN) - m.Push(ARG, kit.Format(val)) -} -func (m *Message) ProcessCommandOpt(arg []string, args ...string) { - if len(arg) > 0 && arg[0] == RUN { - return - } - m.Push("opt", kit.Format(m.OptionSimple(args...))) -} func (m *Message) ProcessField(arg ...Any) { m.Process(PROCESS_FIELD) m.Option(FIELD_PREFIX, arg...) } -func (m *Message) ProcessInner() { m.Process(PROCESS_INNER) } -func (m *Message) ProcessAgain() { m.Process(PROCESS_AGAIN) } -func (m *Message) ProcessHold() { m.Process(PROCESS_HOLD) } -func (m *Message) ProcessBack() { m.Process(PROCESS_BACK) } -func (m *Message) ProcessRich(arg ...Any) { m.Process(PROCESS_RICH, arg...) } -func (m *Message) ProcessGrow(arg ...Any) { m.Process(PROCESS_GROW, arg...) } -func (m *Message) ProcessOpen(url string) { m.Process(PROCESS_OPEN, url) } +func (m *Message) ProcessInner() { m.Process(PROCESS_INNER) } +func (m *Message) ProcessAgain() { m.Process(PROCESS_AGAIN) } +func (m *Message) ProcessHold(text ...string) { m.Process(PROCESS_HOLD) } +func (m *Message) ProcessBack() { m.Process(PROCESS_BACK) } +func (m *Message) ProcessRich(arg ...Any) { m.Process(PROCESS_RICH, arg...) } +func (m *Message) ProcessGrow(arg ...Any) { m.Process(PROCESS_GROW, arg...) } +func (m *Message) ProcessOpen(url string) { m.Process(PROCESS_OPEN, url) } -func (m *Message) OptionUserWeb() *url.URL { - return kit.ParseURL(m.Option(MSG_USERWEB)) +func (m *Message) Display(file string, arg ...Any) *Message { // repos local file + m.Option(MSG_DISPLAY, kit.MergeURL(displayRequire(2, file)[DISPLAY], arg...)) + return m } -func (m *Message) MergeURL2(url string, arg ...Any) string { - return kit.MergeURL2(m.Option(MSG_USERWEB), url, arg...) -} -func (m *Message) MergeLink(url string, arg ...Any) string { - return strings.Split(m.MergeURL2(url, arg...), "?")[0] -} -func (m *Message) MergePod(pod string, arg ...Any) string { - return kit.MergePOD(kit.Select(Info.Domain, m.Option(MSG_USERWEB)), pod, arg...) -} -func (m *Message) MergeCmd(cmd string, arg ...Any) string { - if cmd == "" { - cmd = m.PrefixKey() +func DisplayLocal(file string, arg ...string) Maps { // /plugin/local/file + if file == "" { + file = path.Join(kit.PathName(2), kit.Keys(kit.FileName(2), JS)) } - if m.Option(MSG_USERPOD) == "" { - return kit.MergeURL2(kit.Select(Info.Domain, m.Option(MSG_USERWEB)), path.Join("/chat", "cmd", cmd)) + if !strings.HasPrefix(file, HTTP) && !strings.HasPrefix(file, PS) { + file = path.Join(PLUGIN_LOCAL, file) } - return kit.MergeURL2(kit.Select(Info.Domain, m.Option(MSG_USERWEB)), path.Join("/chat", "pod", m.Option(MSG_USERPOD), "cmd", cmd), arg...) + return DisplayBase(file, arg...) } -func (m *Message) MergeWebsite(web string, arg ...Any) string { - if m.Option(MSG_USERPOD) == "" { - return kit.MergeURL2(kit.Select(Info.Domain, m.Option(MSG_USERWEB)), path.Join("/chat", "website", web)) +func DisplayStory(file string, arg ...string) Maps { // /plugin/story/file + if !strings.HasPrefix(file, HTTP) && !strings.HasPrefix(file, PS) { + file = path.Join(PLUGIN_STORY, file) } - return kit.MergeURL2(kit.Select(Info.Domain, m.Option(MSG_USERWEB)), path.Join("/chat", "pod", m.Option(MSG_USERPOD), "website", web), arg...) + return DisplayBase(file, arg...) +} +func DisplayBase(file string, arg ...string) Maps { + return Maps{DISPLAY: file, STYLE: kit.Join(arg, SP)} +} +func Display(file string, arg ...string) Maps { // repos local file + return displayRequire(2, file, arg...) +} +func displayRequire(n int, file string, arg ...string) Maps { + if file == "" { + file = kit.Keys(kit.FileName(n+1), JS) + } + if !strings.HasPrefix(file, HTTP) && !strings.HasPrefix(file, PS) { + file = path.Join(PS, path.Join(path.Dir(FileRequire(n+2)), file)) + } + return DisplayBase(file, arg...) +} +func FileRequire(n int) string { + p := kit.Split(kit.FileLine(n, 100), DF)[0] + if strings.Contains(p, "go/pkg/mod") { + return path.Join("/require", strings.Split(p, "go/pkg/mod")[1]) + } + return path.Join("/require/"+kit.ModPath(n), path.Base(p)) } diff --git a/render.go b/render.go index 13049d14..551ecf76 100644 --- a/render.go +++ b/render.go @@ -2,7 +2,6 @@ package ice import ( "net/http" - "path" "strings" kit "shylinux.com/x/toolkits" @@ -19,9 +18,6 @@ func Render(m *Message, cmd string, args ...Any) string { switch arg := kit.Simple(args...); cmd { case RENDER_ANCHOR: // [name] link p := kit.Select(arg[0], arg, 1) - if !strings.HasPrefix(p, HTTP) { - p = m.MergeURL2(p) - } return kit.Format(`%s`, p, arg[0]) case RENDER_BUTTON: // name... @@ -61,11 +57,8 @@ func (m *Message) Render(cmd string, args ...Any) *Message { } return m } -func (m *Message) RenderVoid() *Message { - return m.Render(RENDER_VOID) -} -func (m *Message) RenderJson(args ...Any) *Message { // [key value]... - return m.Render(RENDER_JSON, kit.Format(kit.Dict(args...))) +func (m *Message) RenderTemplate(args ...Any) *Message { + return m.Render(RENDER_TEMPLATE, args...) } func (m *Message) RenderStatus(status int) *Message { return m.Render(RENDER_STATUS, status) @@ -82,36 +75,17 @@ func (m *Message) RenderStatusForbidden() *Message { func (m *Message) RenderStatusNotFound() *Message { return m.Render(RENDER_STATUS, http.StatusNotFound) } -func (m *Message) RenderResult(args ...Any) *Message { // [fmt arg...] - return m.Render(RENDER_RESULT, args...) -} -func (m *Message) RenderTemplate(args ...Any) *Message { - return m.Render(RENDER_TEMPLATE, args...) -} func (m *Message) RenderRedirect(args ...Any) *Message { return m.Render(RENDER_REDIRECT, args...) } func (m *Message) RenderDownload(args ...Any) *Message { return m.Render(RENDER_DOWNLOAD, args...) } -func (m *Message) RenderWebsite(pod string, dir string, arg ...string) *Message { - m.Echo(m.Cmdx(m.Space(pod), WEBSITE, "parse", dir, arg)) - return m.RenderResult() +func (m *Message) RenderResult(args ...Any) *Message { // [fmt arg...] + return m.Render(RENDER_RESULT, args...) } -func (m *Message) RenderIndex(serve, repos string, file ...string) *Message { - return m.RenderDownload(path.Join(m.Conf(serve, kit.Keym(repos, "path")), kit.Select(m.Conf(serve, kit.Keym(repos, INDEX)), path.Join(file...)))) -} -func (m *Message) RenderCmd(index string, args ...Any) { - list := index - if index != "" { - msg := m.Cmd(COMMAND, index) - list = kit.Format(kit.List(kit.Dict(msg.AppendSimple(NAME, HELP), - INDEX, index, ARGS, kit.Simple(args), DISPLAY, m.Option(MSG_DISPLAY), - INPUTS, kit.UnMarshal(msg.Append(LIST)), FEATURE, kit.UnMarshal(msg.Append(META)), - ))) - } - m.Echo(kit.Format(Info.cans, list)) - m.RenderResult() +func (m *Message) RenderJson(args ...Any) *Message { // [key value]... + return m.Render(RENDER_JSON, kit.Format(kit.Dict(args...))) } func (m *Message) IsMobileUA() bool { @@ -123,56 +97,6 @@ func (m *Message) IsCliUA() bool { } return false } -func (m *Message) PushAnchor(arg ...Any) { // [name] link - if !m.IsCliUA() { - m.Push(LINK, Render(m, RENDER_ANCHOR, arg...)) - } -} -func (m *Message) PushButton(arg ...Any) { // name... - if !m.IsCliUA() { - if m.FieldsIsDetail() { - for i, k := range m.meta[KEY] { - if k == ACTION { - m.meta[VALUE][i] = Render(m, RENDER_BUTTON, arg...) - return - } - } - } else if len(m.meta[ACTION]) >= m.Length() { - m.meta[ACTION] = []string{} - } - m.Push(ACTION, Render(m, RENDER_BUTTON, arg...)) - } -} -func (m *Message) PushScript(arg ...string) { // [type] text... - if !m.IsCliUA() { - m.Push(SCRIPT, Render(m, RENDER_SCRIPT, arg)) - } -} -func (m *Message) PushQRCode(key string, src string, arg ...string) { // key src [height] - if !m.IsCliUA() { - m.Push(key, Render(m, RENDER_QRCODE, src, arg)) - } -} -func (m *Message) PushImages(key, src string, arg ...string) { // key src [height] - if !m.IsCliUA() { - m.Push(key, Render(m, RENDER_IMAGES, src, arg)) - } -} -func (m *Message) PushVideos(key, src string, arg ...string) { // key src [height] - if !m.IsCliUA() { - m.Push(key, Render(m, RENDER_VIDEOS, src, arg)) - } -} -func (m *Message) PushIFrame(key, src string, arg ...string) { // key src - if !m.IsCliUA() { - m.Push(key, Render(m, RENDER_IFRAME, src, arg)) - } -} -func (m *Message) PushDownload(key string, arg ...Any) { // [name] file - if !m.IsCliUA() { - m.Push(key, Render(m, RENDER_DOWNLOAD, arg...)) - } -} func (m *Message) PushAction(list ...Any) *Message { if len(m.meta[MSG_APPEND]) == 0 { return m @@ -196,23 +120,55 @@ func (m *Message) PushSearch(args ...Any) { } } } -func (m *Message) PushPodCmd(cmd string, arg ...string) { - if m.Length() > 0 && len(m.Appendv(POD)) == 0 { - m.Tables(func(value Maps) { m.Push(POD, m.Option(MSG_USERPOD)) }) +func (m *Message) PushAnchor(arg ...Any) { // [name] link + if !m.IsCliUA() { + m.Push(LINK, Render(m, RENDER_ANCHOR, arg...)) } - - m.Cmd(SPACE, OptionFields("type,name")).Tables(func(value Maps) { - switch value[TYPE] { - case "server", "worker": - if value[NAME] == Info.HostName { - break +} +func (m *Message) PushButton(arg ...Any) { // name... + if !m.IsCliUA() { + if m.FieldsIsDetail() { + for i, k := range m.meta[KEY] { + if k == ACTION { + m.meta[VALUE][i] = Render(m, RENDER_BUTTON, arg...) + return + } } - m.Cmd(SPACE, value[NAME], m.Prefix(cmd), arg).Table(func(index int, val Maps, head []string) { - val[POD] = kit.Keys(value[NAME], val[POD]) - m.Push("", val, head) - }) + } else if len(m.meta[ACTION]) >= m.Length() { + m.meta[ACTION] = []string{} } - }) + m.Push(ACTION, Render(m, RENDER_BUTTON, arg...)) + } +} +func (m *Message) PushImages(key, src string, arg ...string) { // key src [height] + if !m.IsCliUA() { + m.Push(key, Render(m, RENDER_IMAGES, src, arg)) + } +} +func (m *Message) PushVideos(key, src string, arg ...string) { // key src [height] + if !m.IsCliUA() { + m.Push(key, Render(m, RENDER_VIDEOS, src, arg)) + } +} +func (m *Message) PushIFrame(key, src string, arg ...string) { // key src + if !m.IsCliUA() { + m.Push(key, Render(m, RENDER_IFRAME, src, arg)) + } +} +func (m *Message) PushQRCode(key string, src string, arg ...string) { // key src [height] + if !m.IsCliUA() { + m.Push(key, Render(m, RENDER_QRCODE, src, arg)) + } +} +func (m *Message) PushScript(arg ...string) { // [type] text... + if !m.IsCliUA() { + m.Push(SCRIPT, Render(m, RENDER_SCRIPT, arg)) + } +} +func (m *Message) PushDownload(key string, arg ...Any) { // [name] file + if !m.IsCliUA() { + m.Push(key, Render(m, RENDER_DOWNLOAD, arg...)) + } } func (m *Message) EchoAnchor(arg ...Any) *Message { // [name] link @@ -221,12 +177,6 @@ func (m *Message) EchoAnchor(arg ...Any) *Message { // [name] link func (m *Message) EchoButton(arg ...Any) *Message { // name... return m.Echo(Render(m, RENDER_BUTTON, arg...)) } -func (m *Message) EchoScript(arg ...string) *Message { // [type] text... - return m.Echo(Render(m, RENDER_SCRIPT, arg)) -} -func (m *Message) EchoQRCode(src string, arg ...string) *Message { // src [height] - return m.Echo(Render(m, RENDER_QRCODE, src, arg)) -} func (m *Message) EchoImages(src string, arg ...string) *Message { // src [height] return m.Echo(Render(m, RENDER_IMAGES, src, arg)) } @@ -236,76 +186,12 @@ func (m *Message) EchoVideos(src string, arg ...string) *Message { // src [heigh func (m *Message) EchoIFrame(src string, arg ...string) *Message { // src return m.Echo(Render(m, RENDER_IFRAME, src, arg)) } +func (m *Message) EchoQRCode(src string, arg ...string) *Message { // src [height] + return m.Echo(Render(m, RENDER_QRCODE, src, arg)) +} +func (m *Message) EchoScript(arg ...string) *Message { // [type] text... + return m.Echo(Render(m, RENDER_SCRIPT, arg)) +} func (m *Message) EchoDownload(arg ...Any) *Message { // [name] file return m.Echo(Render(m, RENDER_DOWNLOAD, arg...)) } - -func (m *Message) DisplayBase(file string, arg ...Any) *Message { - if !strings.Contains(file, PT) { - file += ".js" - } - m.Option(MSG_DISPLAY, kit.MergeURL(DisplayBase(file)[DISPLAY], arg...)) - return m -} -func (m *Message) DisplayTable(arg ...Any) *Message { // /plugin/story/file - return m.Display(kit.MergeURL("/plugin/table.js", arg...)) -} -func (m *Message) DisplayTableCard(arg ...Any) *Message { // /plugin/story/file - return m.Display(kit.MergeURL("/plugin/table.js", "style", "card")) -} -func (m *Message) DisplayStory(file string, arg ...Any) *Message { // /plugin/story/file - if !strings.HasPrefix(file, HTTP) && !strings.HasPrefix(file, PS) { - file = path.Join(PLUGIN_STORY, file) - } - return m.DisplayBase(file, arg...) -} -func (m *Message) DisplayLocal(file string, arg ...Any) *Message { // /plugin/local/file - if file == "" { - file = path.Join(kit.PathName(2), kit.Keys(kit.FileName(2), JS)) - } - if !strings.HasPrefix(file, HTTP) && !strings.HasPrefix(file, PS) { - file = path.Join(PLUGIN_LOCAL, file) - } - return m.DisplayBase(file, arg...) -} -func (m *Message) Display(file string, arg ...Any) *Message { // repos local file - m.Option(MSG_DISPLAY, kit.MergeURL(displayRequire(2, file)[DISPLAY], arg...)) - return m -} -func (m *Message) DisplayStoryJSON(arg ...Any) *Message { // /plugin/story/json.js - return m.DisplayStory("json", arg...) -} -func (m *Message) DisplayStorySpide(arg ...Any) *Message { // /plugin/story/json.js - return m.DisplayStory("spide", arg...).StatusTimeCount() -} - -func DisplayBase(file string, arg ...string) Maps { - return Maps{DISPLAY: file, STYLE: kit.Join(arg, SP)} -} -func DisplayStory(file string, arg ...string) Maps { // /plugin/story/file - if !strings.HasPrefix(file, HTTP) && !strings.HasPrefix(file, PS) { - file = path.Join(PLUGIN_STORY, file) - } - return DisplayBase(file, arg...) -} -func DisplayLocal(file string, arg ...string) Maps { // /plugin/local/file - if file == "" { - file = path.Join(kit.PathName(2), kit.Keys(kit.FileName(2), JS)) - } - if !strings.HasPrefix(file, HTTP) && !strings.HasPrefix(file, PS) { - file = path.Join(PLUGIN_LOCAL, file) - } - return DisplayBase(file, arg...) -} -func Display(file string, arg ...string) Maps { // repos local file - return displayRequire(2, file, arg...) -} -func displayRequire(n int, file string, arg ...string) Maps { - if file == "" { - file = kit.Keys(kit.FileName(n+1), JS) - } - if !strings.HasPrefix(file, HTTP) && !strings.HasPrefix(file, PS) { - file = path.Join(PS, path.Join(path.Dir(FileRequire(n+2)), file)) - } - return DisplayBase(file, arg...) -} diff --git a/type.go b/type.go index 75563c08..50123f48 100644 --- a/type.go +++ b/type.go @@ -5,23 +5,24 @@ import ( "fmt" "io" "net/http" - "path" "strings" "sync/atomic" "time" kit "shylinux.com/x/toolkits" - "shylinux.com/x/toolkits/logs" ) type Any = interface{} type List = []Any type Map = map[string]Any type Maps = map[string]string -type CommandHandler func(m *Message, arg ...string) +type Handler func(m *Message, arg ...string) type Commands = map[string]*Command type Actions = map[string]*Action type Configs = map[string]*Config +type Caches = map[string]*Cache +type Contexts = map[string]*Context +type Messages = map[string]*Message type Cache struct { Name string @@ -36,32 +37,26 @@ type Config struct { type Action struct { Name string Help string - Hand CommandHandler - List []Any + Hand Handler + List List } type Command struct { Name string Help string - Actions map[string]*Action - Hand CommandHandler - List []Any + Actions Actions + Hand Handler + List List Meta Map } -type Server interface { - Spawn(m *Message, c *Context, arg ...string) Server - Begin(m *Message, arg ...string) Server - Start(m *Message, arg ...string) bool - Close(m *Message, arg ...string) bool -} type Context struct { Name string Help string - Caches map[string]*Cache - Configs map[string]*Config - Commands map[string]*Command + Caches Caches + Configs Configs + Commands Commands - Contexts map[string]*Context + Contexts Contexts context *Context root *Context server Server @@ -71,6 +66,12 @@ type Context struct { id int32 } +type Server interface { + Spawn(m *Message, c *Context, arg ...string) Server + Begin(m *Message, arg ...string) Server + Start(m *Message, arg ...string) bool + Close(m *Message, arg ...string) bool +} func (c *Context) ID() int32 { return atomic.AddInt32(&c.id, 1) @@ -88,9 +89,6 @@ func (c *Context) Server() Server { return c.server } -func (c *Context) RoutePath(arg ...string) string { - return path.Join(strings.TrimPrefix(strings.ReplaceAll(c.Cap(CTX_FOLLOW), PT, PS), "web"), path.Join(arg...)) -} func (c *Context) PrefixKey(arg ...string) string { return kit.Keys(c.Cap(CTX_FOLLOW), arg) } @@ -108,7 +106,7 @@ func (c *Context) Register(s *Context, x Server, n ...string) *Context { } if s.Merge(s); c.Contexts == nil { - c.Contexts = map[string]*Context{} + c.Contexts = Contexts{} } c.Contexts[s.Name] = s s.root = c.root @@ -121,16 +119,16 @@ func (c *Context) MergeCommands(Commands Commands) *Context { } func (c *Context) Merge(s *Context) *Context { if c.Commands == nil { - c.Commands = map[string]*Command{} + c.Commands = Commands{} } if c.Commands[CTX_INIT] == nil { - c.Commands[CTX_INIT] = &Command{Hand: func(m *Message, arg ...string) { m.Load() }} + 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) { m.Save() }} + c.Commands[CTX_EXIT] = &Command{Hand: func(m *Message, arg ...string) { Info.Save(m) }} } - merge := func(pre *Command, before bool, key string, cmd *Command, cb ...CommandHandler) { + merge := func(pre *Command, before bool, key string, cmd *Command, cb ...Handler) { last := pre.Hand pre.Hand = func(m *Message, arg ...string) { if before { @@ -211,13 +209,13 @@ func (c *Context) Merge(s *Context) *Context { } if c.Configs == nil { - c.Configs = map[string]*Config{} + c.Configs = Configs{} } for k, v := range s.Configs { c.Configs[k] = v } if c.Caches == nil { - c.Caches = map[string]*Cache{} + c.Caches = Caches{} } for k, v := range s.Caches { c.Caches[k] = v @@ -242,7 +240,6 @@ func (c *Context) Begin(m *Message, arg ...string) *Context { 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: ""} - // m.Log(LOG_BEGIN, c.Cap(CTX_FOLLOW)) if c.begin = m; c.server != nil { c.server.Begin(m, arg...) @@ -253,24 +250,19 @@ func (c *Context) Start(m *Message, arg ...string) bool { wait := make(chan bool, 1) defer func() { <-wait }() - _source := m.target.Name - if c.server != nil { - _source = logs.FileLine(c.server.Start, 3) - } m.Go(func() { - - m.Log(LOG_START, c.Cap(CTX_FOLLOW)) + m.Log(CTX_START, c.Cap(CTX_FOLLOW)) c.Cap(CTX_STATUS, CTX_START) wait <- true if c.start = m; c.server != nil { c.server.Start(m, arg...) } - }, _source) + }) return true } func (c *Context) Close(m *Message, arg ...string) bool { - m.Log(LOG_CLOSE, c.Cap(CTX_FOLLOW)) + m.Log(CTX_CLOSE, c.Cap(CTX_FOLLOW)) c.Cap(CTX_STATUS, CTX_CLOSE) if c.server != nil { @@ -298,11 +290,10 @@ type Message struct { _key string _sub string - cb func(*Message) *Message - W http.ResponseWriter - R *http.Request - O io.Writer - I io.Reader + W http.ResponseWriter + R *http.Request + O io.Writer + I io.Reader } func (m *Message) Time(args ...Any) string { // [duration] [format [args...]] @@ -336,8 +327,6 @@ func (m *Message) Spawn(arg ...Any) *Message { msg := &Message{ time: time.Now(), code: int(m.target.root.ID()), meta: map[string][]string{}, data: Map{}, - - _source: m._source, message: m, root: m.root, 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, @@ -433,7 +422,6 @@ func (m *Message) Search(key string, cb Any) *Message { break } } - // if m.Warn(p == nil, ErrNotFound, key) { if p == nil { return m } @@ -545,7 +533,7 @@ func (m *Message) Confv(arg ...Any) (val Any) { // key sub val key := kit.Format(arg[0]) if key == "" { - key = m.PrefixKey() + key = m._key } if conf, ok := m.target.Configs[key]; ok { run(conf)