1
0
forked from x/icebergs
This commit is contained in:
IT 老营长 @云轩领航-创始人 2023-09-19 21:35:37 +08:00
parent b3520df582
commit d9dcd6480c
64 changed files with 628 additions and 793 deletions

View File

@ -31,14 +31,7 @@ func init() {
Index.MergeCommands(ice.Commands{
EMAIL: {Name: "email name auto create mailbox", Help: "邮件", Actions: ice.MergeActions(ice.Actions{
MAILBOX: {Help: "邮箱", Hand: func(m *ice.Message, arg ...string) { m.EchoIFrame(mdb.Config(m, MAILBOX)).ProcessInner() }},
mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) {
mdb.HashInputs(m, arg)
switch arg[0] {
case CONTENT:
m.Push(arg[0], m.Option(ice.MSG_USERWEB))
}
}},
SEND: {Name: "send to*='shylinux@163.com' cc subject*=hi content*:textarea=hello", Help: "发送", Hand: func(m *ice.Message, arg ...string) {
SEND: {Name: "send to*='shy@shylinux.com' cc subject*=hi content*:textarea=hello", Help: "发送", Hand: func(m *ice.Message, arg ...string) {
msg := m.Cmd("", m.OptionDefault(mdb.NAME, ADMIN))
if m.Warn(msg.Append(SERVICE) == "", ice.ErrNotValid, SERVICE) {
return

View File

@ -15,9 +15,9 @@ const OFFER = "offer"
func init() {
Index.MergeCommands(ice.Commands{
OFFER: {Name: "offer hash auto", Help: "邀请", Actions: ice.MergeActions(ice.Actions{
mdb.CREATE: {Name: "create email*='shylinux@163.com' subject content", Help: "邀请", Hand: func(m *ice.Message, arg ...string) {
mdb.CREATE: {Name: "create email*='shy@shylinux.com' subject content", Help: "邀请", Hand: func(m *ice.Message, arg ...string) {
h := mdb.HashCreate(m.Spawn(), m.OptionSimple(EMAIL, SUBJECT, CONTENT), INVITE, m.Option(ice.MSG_USERNAME), mdb.STATUS, INVITE)
m.Cmd(EMAIL, SEND, m.Option(EMAIL), m.OptionDefault(SUBJECT, "welcome to contexts, please continue"),
m.Cmd(EMAIL, SEND, m.Option(EMAIL), "", m.OptionDefault(SUBJECT, "welcome to contexts, please continue"),
m.OptionDefault(CONTENT, ice.Render(m, ice.RENDER_ANCHOR, m.Cmdx("host", "publish", m.MergePodCmd("", "", mdb.HASH, h)))),
)
}},

View File

@ -85,10 +85,7 @@ func init() {
kit.If(_role_right(m, arg[0], kit.Split(_role_keys(arg[1:]...), ice.PT)...), func() { m.Echo(ice.OK) })
}},
"whiteblack": {Hand: func(m *ice.Message, arg ...string) {
kit.For(arg, func(cmd string) {
m.Cmd(ROLE, WHITE, VOID, cmd)
m.Cmd(ROLE, BLACK, VOID, cmd, ice.ACTION)
})
kit.For(arg, func(cmd string) { m.Cmd(ROLE, WHITE, VOID, cmd); m.Cmd(ROLE, BLACK, VOID, cmd, ice.ACTION) })
}},
}, mdb.HashAction(mdb.SHORT, mdb.NAME)), Hand: func(m *ice.Message, arg ...string) {
_role_list(m, kit.Select("", arg, 0)).PushAction(mdb.DELETE)

View File

@ -47,7 +47,7 @@ func init() {
m.Push(arg[0], m.Option(ice.MSG_USERNAME))
}
}},
mdb.CREATE: {Name: "create usernick username* userrole=void,tech userzone background", Hand: func(m *ice.Message, arg ...string) {
mdb.CREATE: {Name: "create usernick username* userrole=void,tech userzone", Hand: func(m *ice.Message, arg ...string) {
_user_create(m, m.Option(USERNAME), m.OptionSimple(USERNICK, USERROLE, USERZONE, BACKGROUND, AVATAR, AVATAR_URL, EMAIL, LANGUAGE)...)
}},
}, mdb.ImportantHashAction(mdb.SHORT, USERNAME, mdb.FIELD, "time,usernick,username,userrole,userzone"))},

View File

@ -66,6 +66,8 @@ const (
YELLOW = "yellow"
RANDOM = "random"
GLASS = "#0000"
LIGHT = "light"
DARK = "dark"
)
func Color(m *ice.Message, c string, str ice.Any) string {

View File

@ -57,9 +57,7 @@ func _daemon_exec(m *ice.Message, cmd *exec.Cmd) {
default:
m.ErrorNotImplement(cb)
}
for _, p := range kit.Simple(CMD_INPUT, CMD_OUTPUT, CMD_ERRPUT) {
nfs.Close(m, m.Optionv(p))
}
kit.For(kit.Simple(CMD_INPUT, CMD_OUTPUT, CMD_ERRPUT), func(p string) { nfs.Close(m, m.Optionv(p)) })
})
}
@ -67,6 +65,7 @@ const (
DIR = "dir"
ENV = "env"
API = "api"
MOD = "mod"
PID = "pid"
PWD = "pwd"
)

View File

@ -25,9 +25,7 @@ func BinPath(arg ...string) string {
kit.If(strings.TrimSpace(l) != "" && !strings.HasPrefix(strings.TrimSpace(l), "#"), func() { push(kit.Path(p, l)) })
})
})
push("/usr/local/bin")
kit.For(strings.Split(kit.Env(PATH), _path_sep()), func(p string) { push(p) })
return kit.Join(list, _path_sep())
}

View File

@ -1,7 +1,6 @@
package cli
import (
"io"
"runtime"
"strings"
@ -15,6 +14,7 @@ import (
const (
CMD = "cmd"
ADD = "add"
OSID = "osid"
REPOS = "repos"
UBUNTU = "ubuntu"
@ -39,41 +39,44 @@ func init() {
kit.If(strings.Contains(osid, kit.Format(value[OSID])), func() { m.Cmdy(kit.Split(kit.Format(value[CMD]))) })
})
}},
ALPINE: {Name: "alpine cli cmd", Hand: func(m *ice.Message, arg ...string) { IsAlpine(m, arg...) }},
REPOS: {Help: "镜像源", Hand: func(m *ice.Message, arg ...string) {
switch {
case strings.Contains(release(m.Spawn()), ALPINE):
ice.Info.PushStream(m)
m.Optionv(CMD_OUTPUT).(io.Writer).Write([]byte("\n"))
defer ice.Info.PushNotice(m, "toast", "success")
m.Cmd(nfs.SAVE, ETC_APK_REPOS, strings.ReplaceAll(m.Cmdx(nfs.CAT, ETC_APK_REPOS), "dl-cdn.alpinelinux.org", "mirrors.tencent.com"))
m.Cmdy(SYSTEM, "apk", "update")
m.StatusTimeCount()
}
}},
"add": {Help: "安装", Hand: func(m *ice.Message, arg ...string) {
ADD: {Help: "安装", Hand: func(m *ice.Message, arg ...string) {
mdb.ZoneSelect(m, m.Option(CLI)).Table(func(value ice.Maps) {
ice.Info.PushStream(m)
ice.Info.PushNotice(m, "toast", "process", "", "-1")
defer ice.Info.PushNotice(m, "toast", "success")
m.Push("res", m.Cmdx(kit.Split(value[CMD])))
m.Toast(ice.PROCESS, "", "-1")
if msg := m.Cmd(kit.Split(value[CMD])); IsSuccess(msg) {
m.Toast(ice.SUCCESS)
} else {
m.Toast(ice.FAILURE)
}
})
}},
REPOS: {Name: "repos proxy=mirrors.tencent.com", Help: "镜像", Hand: func(m *ice.Message, arg ...string) {
switch {
case strings.Contains(_release, ALPINE):
m.Toast(ice.PROCESS, "", "-1")
defer m.Toast(ice.SUCCESS)
ice.Info.PushStream(m)
kit.If(m.Option("proxy"), func(p string) {
m.Cmd(nfs.SAVE, ETC_APK_REPOS, strings.ReplaceAll(m.Cmdx(nfs.CAT, ETC_APK_REPOS), "dl-cdn.alpinelinux.org", p))
})
m.Cmdy(SYSTEM, "apk", "update").StatusTime()
}
}},
ALPINE: {Name: "alpine cli cmd", Hand: func(m *ice.Message, arg ...string) { IsAlpine(m, arg...) }},
}, mdb.ZoneAction(mdb.SHORT, CLI, mdb.FIELD, "time,id,osid,cmd"), mdb.ClearOnExitHashAction()), Hand: func(m *ice.Message, arg ...string) {
if mdb.ZoneSelect(m, arg...); len(arg) == 0 {
m.Table(func(value ice.Maps) {
p := SystemFind(m, value[CLI])
m.Push("path", p)
if p == "" {
m.PushButton("add")
if m.Push(nfs.PATH, p); p == "" {
m.PushButton(ADD)
} else {
m.PushButton("")
}
})
m.StatusTimeCount("release", release(m.Spawn()))
m.StatusTimeCount("release", _release)
}
switch {
case strings.Contains(release(m.Spawn()), ALPINE):
case strings.Contains(_release, ALPINE):
m.Cmdy(nfs.CAT, ETC_APK_REPOS)
}
}},
@ -87,17 +90,17 @@ func release(m *ice.Message) string {
if list[0] != LINUX || !nfs.Exists(m, ETC_OS_RELEASE) {
return list[0]
}
m.Option(nfs.CAT_CONTENT, _release)
_release = m.Cmdx(nfs.CAT, ETC_OS_RELEASE, kit.Dict(ice.MSG_USERROLE, aaa.ROOT), func(text string, _ int) string {
m.Cmd(nfs.CAT, ETC_OS_RELEASE, kit.Dict(ice.MSG_USERROLE, aaa.ROOT), func(text string, _ int) string {
if ls := kit.Split(text, mdb.EQ); len(ls) > 1 {
kit.Switch(ls[0], []string{"ID", "ID_LIKE"}, func() { list = append(list, strings.TrimSpace(ls[1])) })
}
return text
})
return strings.Join(list, lex.SP)
_release = strings.Join(list, lex.SP)
return _release
}
func insert(m *ice.Message, sys, cmd string, arg ...string) bool {
if !strings.Contains(release(m), sys) {
if !strings.Contains(_release, sys) {
return false
}
if len(arg) > 0 {

View File

@ -89,7 +89,7 @@ func init() {
}, mdb.PageListAction(mdb.FIELD, "time,id,utime,vmrss,user,idle,free,rx,tx,established,time_wait")), Hand: func(m *ice.Message, arg ...string) {
m.OptionDefault(mdb.CACHE_LIMIT, mdb.Config(m, mdb.LEAST))
if mdb.PageListSelect(m, arg...); (len(arg) == 0 || arg[0] == "") && m.Length() > 0 {
m.SortInt(mdb.ID).Display("/plugin/story/trend.js", ice.VIEW, "折线图", "min", "0", "max", "1000", COLOR, "yellow,cyan,red,green,blue,purple,purple")
m.SortInt(mdb.ID).Display("/plugin/story/trend.js", "view", "折线图", "min", "0", "max", "1000", COLOR, "yellow,cyan,red,green,blue,purple,purple")
m.Status("from", m.Append(mdb.TIME), "span", kit.FmtDuration(time.Duration(kit.Time(m.Time())-kit.Time(m.Append(mdb.TIME)))), m.AppendSimple(mdb.Config(m, mdb.FIELD)), "cursor", "0")
}
}},

View File

@ -61,7 +61,7 @@ func init() {
}},
}, Hand: func(m *ice.Message, arg ...string) {
switch m.Option(ice.MSG_THEME) {
case "light", "white":
case LIGHT, WHITE:
m.Option(FG, kit.Select(BLACK, arg, 1))
m.Option(BG, kit.Select(WHITE, arg, 2))
default:

View File

@ -112,7 +112,7 @@ const (
LINUX = "linux"
MACOS = "macos"
DARWIN = "darwin"
WINDOWS = "windows"
WINDOWS = ice.WINDOWS
)
const (
PATH = "PATH"
@ -129,16 +129,13 @@ const (
CTX_HUB = "ctx_hub"
CTX_DEV = "ctx_dev"
CTX_OPS = "ctx_ops"
CTX_ARG = "ctx_arg"
CTX_PID = "ctx_pid"
CTX_LOG = "ctx_log"
CTX_POD = "ctx_pod"
CTX_ENV = "ctx_env"
CTX_DAEMON = "ctx_daemon"
)
var ENV_LIST = []string{TZ, LANG, TERM, SHELL, CTX_SHY, CTX_HUB, CTX_COM, CTX_DEV, CTX_OPS, CTX_ARG, CTX_PID, CTX_DAEMON}
var ENV_LIST = []string{TZ, LANG, TERM, SHELL, CTX_SHY, CTX_HUB, CTX_COM, CTX_DEV, CTX_OPS, CTX_PID}
const (
HOSTNAME = "hostname"
@ -183,6 +180,10 @@ func init() {
kit.If(len(arg) > 0, func() { runtime.GOMAXPROCS(kit.Int(mdb.Conf(m, RUNTIME, kit.Keys(HOST, MAXPROCS), arg[0]))) })
m.Echo("%d", runtime.GOMAXPROCS(0))
}},
aaa.ROLE: {Hand: func(m *ice.Message, arg ...string) {
m.Cmd(aaa.ROLE, func(value ice.Maps) { m.Push(mdb.KEY, kit.Keys(value[aaa.ROLE], value[mdb.ZONE], value[mdb.KEY])) })
ctx.DisplayStorySpide(m.Options(nfs.DIR_ROOT, "ice."), mdb.FIELD, mdb.KEY, lex.SPLIT, nfs.PT)
}},
API: {Hand: func(m *ice.Message, arg ...string) {
if len(arg) > 1 {
m.Cmdy(ctx.COMMAND, "web.code.inner").Push(ctx.ARGS, kit.Format(nfs.SplitPath(m, m.Option(nfs.FILE))))
@ -205,10 +206,21 @@ func init() {
m.OptionFields(ctx.INDEX, mdb.NAME, mdb.HELP, nfs.FILE)
m.Cmdy(ctx.COMMAND, mdb.SEARCH, ctx.COMMAND).StatusTimeCount()
}},
"mod": {Hand: func(m *ice.Message, arg ...string) {
MOD: {Hand: func(m *ice.Message, arg ...string) {
kit.For(ice.Info.Gomod, func(k string, v string) { m.Push(nfs.MODULE, k).Push(nfs.VERSION, v) })
m.StatusTimeCount()
}},
ENV: {Hand: func(m *ice.Message, arg ...string) {
kit.For(os.Environ(), func(v string) {
ls := strings.SplitN(v, mdb.EQ, 2)
m.Push(mdb.NAME, ls[0]).Push(mdb.VALUE, ls[1])
})
m.StatusTimeCount().Sort(mdb.NAME)
}},
nfs.PATH: {Hand: func(m *ice.Message, arg ...string) {
kit.For(_path_split(os.Getenv(PATH)), func(p string) { m.Push(nfs.PATH, p) })
}},
"chain": {Hand: func(m *ice.Message, arg ...string) { m.Echo(m.FormatChain()) }},
"routine": {Hand: func(m *ice.Message, arg ...string) {
status := map[string]int{}
buf := make([]byte, 4096*4096)
@ -217,7 +229,7 @@ func init() {
for _, v := range bytes.Split(buf, []byte(lex.NL+lex.NL)) {
ls := bytes.Split(v, []byte(lex.NL))
if ls := strings.SplitN(string(ls[0]), " ", 3); len(ls) > 0 {
m.Push(mdb.ID, ls[1]).Push("status", ls[2])
m.Push(mdb.ID, ls[1]).Push(mdb.STATUS, ls[2])
status[kit.Split(string(ls[2]), " []:")[0]]++
}
for i := 1; i < len(ls); i += 2 {
@ -233,17 +245,6 @@ func init() {
m.StatusTimeCount(status, "GOMAXPROCS", runtime.GOMAXPROCS(0), "NumGC", stats.NumGC, "Alloc", kit.FmtSize(int64(stats.Alloc)), "Sys", kit.FmtSize(int64(stats.Sys)))
m.Echo("%v", string(buf))
}},
ENV: {Hand: func(m *ice.Message, arg ...string) {
kit.For(os.Environ(), func(v string) {
ls := strings.SplitN(v, mdb.EQ, 2)
m.Push(mdb.NAME, ls[0]).Push(mdb.VALUE, ls[1])
})
m.StatusTimeCount().Sort(mdb.NAME)
}},
nfs.PATH: {Hand: func(m *ice.Message, arg ...string) {
kit.For(_path_split(os.Getenv(PATH)), func(p string) { m.Push(nfs.PATH, p) })
}},
"chain": {Hand: func(m *ice.Message, arg ...string) { m.Echo(m.FormatChain()) }},
"upgrade": {Help: "升级", Hand: func(m *ice.Message, arg ...string) {
if nfs.Exists(m, ".git") {
m.Cmdy("web.code.compile")
@ -252,7 +253,7 @@ func init() {
}
}},
RESTART: {Help: "重启", Hand: func(m *ice.Message, arg ...string) {
m.Go(func() { m.Sleep("30ms", ice.EXIT, 1) })
m.Go(func() { m.Sleep30ms(ice.EXIT, 1) })
}},
"logs": {Help: "日志", Hand: func(m *ice.Message, arg ...string) {
OpenCmds(m, kit.Format("cd %s", kit.Path("")), "tail -f var/log/bench.log")
@ -260,10 +261,6 @@ func init() {
"conf": {Help: "配置", Hand: func(m *ice.Message, arg ...string) {
OpenCmds(m, kit.Format("cd %s", kit.Path("")), "vim etc/init.shy")
}},
aaa.ROLE: {Hand: func(m *ice.Message, arg ...string) {
m.Cmd(aaa.ROLE, func(value ice.Maps) { m.Push(mdb.KEY, kit.Keys(value[aaa.ROLE], value[mdb.ZONE], value[mdb.KEY])) })
ctx.DisplayStorySpide(m.Options(nfs.DIR_ROOT, "ice."), mdb.FIELD, mdb.KEY, lex.SPLIT, nfs.PT)
}},
}, ctx.CmdAction(), ctx.ConfAction("")), Hand: func(m *ice.Message, arg ...string) {
kit.If(len(arg) > 0 && arg[0] == BOOTINFO, func() { arg = arg[1:] })
m.Cmdy(ctx.CONFIG, RUNTIME, arg)

View File

@ -6,7 +6,6 @@ import (
"net/http"
"os/exec"
"path"
"runtime"
"strings"
ice "shylinux.com/x/icebergs"
@ -14,7 +13,6 @@ import (
"shylinux.com/x/icebergs/base/lex"
"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"
)
@ -156,15 +154,6 @@ const SYSTEM = "system"
func init() {
Index.MergeCommands(ice.Commands{
SYSTEM: {Name: "system cmd", Help: "系统命令", Actions: ice.MergeActions(ice.Actions{
mdb.SEARCH: {Hand: func(m *ice.Message, arg ...string) {
if runtime.GOOS == DARWIN && tcp.IsLocalHost(m, m.Option(ice.MSG_USERIP)) {
if arg[0] == m.CommandKey() && arg[1] == OPENS {
for _, p := range []string{"/Applications", "/System/Applications", "/System/Applications/Utilities"} {
m.Cmd(nfs.DIR, p, mdb.NAME, func(value ice.Maps) { m.PushSearch(mdb.TEXT, path.Join(p, value[mdb.NAME]), value) })
}
}
}
}},
nfs.PUSH: {Hand: func(m *ice.Message, arg ...string) {
for _, p := range arg {
if !strings.Contains(m.Cmdx(nfs.CAT, ice.ETC_PATH), p) {
@ -173,20 +162,16 @@ func init() {
}
m.Cmdy(nfs.CAT, ice.ETC_PATH)
}},
OPENS: {Hand: func(m *ice.Message, arg ...string) { Opens(m, arg...) }},
FIND: {Hand: func(m *ice.Message, arg ...string) { m.Echo(_system_find(m, arg[0], arg[1:]...)) }},
MAN: {Hand: func(m *ice.Message, arg ...string) {
if len(arg) == 1 {
arg = append(arg, "")
}
kit.If(len(arg) == 1, func() { arg = append(arg, "") })
m.Echo(SystemCmds(m, "man %s %s|col -b", kit.Select("", arg[1], arg[1] != "1"), arg[0]))
}},
}, mdb.HashAction(mdb.SHORT, "cmd", mdb.FIELD, "time,cmd,arg")), Hand: func(m *ice.Message, arg ...string) {
OPENS: {Hand: func(m *ice.Message, arg ...string) { Opens(m, arg...) }},
}, mdb.HashAction(mdb.SHORT, CMD, mdb.FIELD, "time,cmd,arg")), Hand: func(m *ice.Message, arg ...string) {
if len(arg) == 0 {
mdb.HashSelect(m)
return
}
if _system_exec(m, _system_cmd(m, arg...)); IsSuccess(m) && m.Append(CMD_ERR) == "" {
} else if _system_exec(m, _system_cmd(m, arg...)); IsSuccess(m) && m.Append(CMD_ERR) == "" {
m.SetAppend()
}
}},

View File

@ -26,7 +26,6 @@ func _command_list(m *ice.Message, name string) *ice.Message {
if strings.HasPrefix(name, "can.") {
return m.Push(mdb.INDEX, name).Push(mdb.NAME, name).Push(mdb.HELP, "").Push(mdb.META, "").Push(mdb.LIST, "")
}
m.Spawn(m.Source()).Search(name, func(p *ice.Context, s *ice.Context, key string, cmd *ice.Command) {
m.Push(mdb.INDEX, kit.Keys(s.Prefix(), key))
m.Push(mdb.NAME, kit.Format(cmd.Name))
@ -42,22 +41,21 @@ func _command_search(m *ice.Message, kind, name, text string) {
return
}
m.PushSearch(ice.CTX, kit.PathName(1), ice.CMD, kit.FileName(1), kit.SimpleKV("", s.Prefix(), cmd.Name, cmd.Help),
CONTEXT, s.Prefix(), COMMAND, key, INDEX, kit.Keys(s.Prefix(), key), mdb.HELP, cmd.Help, nfs.FILE, FileURI(cmd.FileLine()),
)
CONTEXT, s.Prefix(), COMMAND, key, INDEX, kit.Keys(s.Prefix(), key), mdb.HELP, cmd.Help, nfs.FILE, FileURI(cmd.FileLine()))
})
m.Sort(m.OptionFields())
}
const (
INDEX = "index"
OPTS = "opts"
ARGS = "args"
SHIP = "ship"
OPTS = "opts"
STYLE = "style"
DISPLAY = "display"
ACTION = "action"
RUN = "run"
TOOLS = "tools"
RUN = "run"
SHIP = "ship"
)
const COMMAND = "command"
@ -72,11 +70,6 @@ func init() {
_command_search(m, arg[0], kit.Select("", arg, 1), kit.Select("", arg, 2))
}
}},
mdb.EXPORT: {Hand: func(m *ice.Message, arg ...string) {
TravelCmd(m, func(key, file, line string) { m.Push(mdb.NAME, key).Push(nfs.FILE, file).Push(nfs.LINE, line) }).Sort(mdb.NAME).Table(func(value ice.Maps) {
m.Echo(`%s %s %s;" f`+lex.NL, value[mdb.NAME], value[nfs.FILE], value[nfs.LINE])
}).Cmd(nfs.SAVE, nfs.TAGS, m.Result())
}},
mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) {
if len(arg) > 0 && arg[0] != "" && arg[0] != ice.EXIT {
m.Search(arg[0], func(key string, cmd *ice.Command) {
@ -87,33 +80,26 @@ func init() {
})
}
}},
mdb.EXPORT: {Hand: func(m *ice.Message, arg ...string) {
TravelCmd(m, func(key, file, line string) { m.Push(mdb.NAME, key).Push(nfs.FILE, file).Push(nfs.LINE, line) }).Sort(mdb.NAME).Table(func(value ice.Maps) {
m.Echo(`%s %s %s;" f`+lex.NL, value[mdb.NAME], value[nfs.FILE], value[nfs.LINE])
}).Cmd(nfs.SAVE, nfs.TAGS, m.Result())
}},
}, CmdAction(), aaa.RoleAction()), Hand: func(m *ice.Message, arg ...string) {
if len(arg) == 0 {
m.Cmdy("", mdb.SEARCH, COMMAND, ice.OptionFields(INDEX)).StatusTimeCount()
DisplayStory(m.Options(nfs.DIR_ROOT, "ice."), "spide.js?split=.")
return
}
kit.If(len(arg) == 0, func() { arg = append(arg, "") })
} else {
kit.For(arg, func(k string) { _command_list(m, k) })
}
}},
})
}
var Upload = func(*ice.Message) []string { return nil }
func CmdInputs(m *ice.Message, arg ...string) {
switch arg[0] {
case INDEX:
m.Cmdy(COMMAND, mdb.SEARCH, COMMAND, ice.OptionFields(INDEX))
case ARGS:
if m.Cmdy(m.Option(INDEX), mdb.INPUTS, arg); m.Length() == 0 {
m.Cmdy(m.Option(INDEX))
}
}
}
func PodCmd(m *ice.Message, arg ...ice.Any) bool {
Upload(m)
// for _, key := range []string{ice.SPACE, ice.POD} {
for _, key := range []string{ice.POD} {
if pod := m.Option(key); pod != "" {
m.Options(key, []string{}, ice.MSG_USERPOD, pod).Cmdy(append(kit.List(ice.SPACE, pod), arg...)...)
@ -128,21 +114,29 @@ func Run(m *ice.Message, arg ...string) {
func Command(m *ice.Message, arg ...string) {
kit.If(!PodCmd(m, COMMAND, arg), func() { m.Cmdy(COMMAND, arg) })
}
func CmdHandler(args ...ice.Any) ice.Handler {
return func(m *ice.Message, arg ...string) { m.Cmdy(args...) }
}
func CmdAction(args ...ice.Any) ice.Actions {
return ice.Actions{ice.CTX_INIT: mdb.AutoConfig(args...), ice.RUN: {Hand: Run}, COMMAND: {Hand: Command}}
}
func CmdHandler(args ...ice.Any) ice.Handler {
return func(m *ice.Message, arg ...string) { m.Cmdy(args...) }
}
func CmdList(m *ice.Message) *ice.Message {
return m.Cmdy(COMMAND, mdb.SEARCH, COMMAND, ice.OptionFields(INDEX))
}
func CmdInputs(m *ice.Message, arg ...string) {
switch arg[0] {
case INDEX:
m.Cmdy(COMMAND, mdb.SEARCH, COMMAND, ice.OptionFields(INDEX))
case ARGS:
if m.Cmdy(m.Option(INDEX), mdb.INPUTS, arg); m.Length() == 0 {
m.Cmdy(m.Option(INDEX))
}
}
}
func IsOrderCmd(key string) bool { return key[0] == '/' || key[0] == '_' }
func FileURI(dir string) string {
if runtime.GOOS == "windows" {
dir = strings.ReplaceAll(dir, "\\", "/")
}
kit.If(runtime.GOOS == ice.WINDOWS, func() { dir = strings.ReplaceAll(dir, "\\", nfs.PS) })
if dir == "" {
return ""
} else if strings.Contains(dir, "/pkg/mod/") {
@ -151,8 +145,10 @@ func FileURI(dir string) string {
dir = strings.TrimPrefix(dir, ice.Info.Make.Path)
} else if strings.HasPrefix(dir, kit.Path("")+nfs.PS) {
dir = strings.TrimPrefix(dir, kit.Path("")+nfs.PS)
} else if strings.HasPrefix(dir, ".ish/pluged/") {
dir = strings.TrimPrefix(dir, ".ish/pluged/")
} else if strings.HasPrefix(dir, ice.ISH_PLUGED) {
dir = strings.TrimPrefix(dir, ice.ISH_PLUGED)
} else if kit.HasPrefix(dir, nfs.PS, ice.HTTP) {
return dir
}
return path.Join(nfs.PS, ice.REQUIRE, dir)
}
@ -200,7 +196,7 @@ func TravelCmd(m *ice.Message, cb func(key, file, line string)) *ice.Message {
if IsOrderCmd(key) {
return
}
if runtime.GOOS == "windows" {
if runtime.GOOS == ice.WINDOWS {
if ls := kit.Split(cmd.FileLine(), nfs.DF); len(ls) > 2 {
cb(kit.Keys(s.Prefix(), key), strings.TrimPrefix(strings.Join(kit.Slice(ls, 0, -1), nfs.DF), kit.Path("")+nfs.PS), kit.Select("1", ls, -1))
return

View File

@ -13,62 +13,6 @@ import (
"shylinux.com/x/toolkits/miss"
)
func FormatPretty(v ice.Any, i, n int) string {
return kit.Formats(v)
switch v := v.(type) {
case map[string]ice.Any:
if n == 0 {
list := []string{"{"}
kit.For(v, func(k string, v ice.Any) {
list = append(list, kit.Format("%q", k), nfs.DF, FormatPretty(v, 0, 0), mdb.FS)
})
list = list[:len(list)-1]
list = append(list, "}")
return strings.Join(list, "")
}
list := []string{"{", lex.NL}
kit.For(v, func(k string, v ice.Any) {
list = append(list, strings.Repeat(lex.TB, i+1), kit.Format("%q", k), nfs.DF)
if i < n && !kit.IsIn(k, mdb.META) && !strings.HasPrefix(k, "_") {
list = append(list, FormatPretty(v, i+1, n))
} else {
list = append(list, FormatPretty(v, 0, 0))
}
list = append(list, mdb.FS, lex.NL)
})
list = append(list[:len(list)-2], lex.NL)
list = append(list, strings.Repeat(lex.TB, i), "}")
return strings.Join(list, "")
case []ice.Any:
if n == 0 {
list := []string{"["}
kit.For(v, func(k string, v ice.Any) {
list = append(list, FormatPretty(v, 0, 0), mdb.FS)
})
list = list[:len(list)-1]
list = append(list, "]")
return strings.Join(list, "")
}
list := []string{"[", lex.NL}
kit.For(v, func(v ice.Any) {
list = append(list, strings.Repeat(lex.TB, i+1))
if i < n {
list = append(list, FormatPretty(v, i+1, n))
} else {
list = append(list, FormatPretty(v, 0, 0))
}
list = append(list, mdb.FS, lex.NL)
})
list = append(list[:len(list)-2], lex.NL)
list = append(list, strings.Repeat(lex.TB, i), "]")
return strings.Join(list, "")
case string:
return kit.Format(v)
return kit.Format("%q", v)
default:
return kit.Format(v)
}
}
func _config_format_list(m *ice.Message, v ice.Any) string {
list := []string{"{", lex.NL}
kit.For(v, func(k string, v ice.Any) {
@ -100,7 +44,7 @@ func _config_only(v ice.Any, arg ...string) bool {
continue
} else {
for k := range v {
if kit.IsIn(k, "important") && len(v) > 1 {
if kit.IsIn(k, mdb.IMPORTANT) && len(v) > 1 {
return false
}
}
@ -139,15 +83,9 @@ func _config_load(m *ice.Message, name string, arg ...string) {
data, msg := ice.Map{}, m.Spawn(m.Source())
json.NewDecoder(f).Decode(&data)
for k, v := range data {
if k == "web.chat.header" {
m.Debug("what %v", v)
}
msg.Search(k, func(p *ice.Context, s *ice.Context, key string, conf *ice.Config) {
kit.If(s.Configs[key] == nil, func() { s.Configs[key] = &ice.Config{} })
s.Configs[key].Value = v
if key == "header" {
m.Debug("what %v", v)
}
})
}
}
@ -216,12 +154,12 @@ func init() {
}
func Save(m *ice.Message, arg ...string) *ice.Message {
kit.If(len(arg) == 0, func() { arg = kit.SortedKey(m.Target().Configs) })
kit.For(arg, func(i int, k string) { arg[i] = strings.Replace(m.Prefix(k), "/", "", 1) })
kit.For(arg, func(i int, k string) { arg[i] = strings.Replace(m.Prefix(k), nfs.PS, "", 1) })
return m.Cmd(CONFIG, SAVE, m.Prefix(nfs.JSON), arg)
}
func Load(m *ice.Message, arg ...string) *ice.Message {
kit.If(len(arg) == 0, func() { arg = kit.SortedKey(m.Target().Configs) })
kit.For(arg, func(i int, k string) { arg[i] = strings.Replace(m.Prefix(k), "/", "", 1) })
kit.For(arg, func(i int, k string) { arg[i] = strings.Replace(m.Prefix(k), nfs.PS, "", 1) })
return m.Cmd(CONFIG, LOAD, m.Prefix(nfs.JSON), arg)
}
func ConfAction(arg ...ice.Any) ice.Actions { return ice.Actions{ice.CTX_INIT: mdb.AutoConfig(arg...)} }
@ -241,3 +179,59 @@ func OptionFromConfig(m *ice.Message, arg ...string) string {
kit.For(arg, func(k string) { m.Option(k, mdb.Config(m, k)) })
return m.Option(arg[0])
}
func FormatPretty(v ice.Any, i, n int) string {
return kit.Formats(v)
switch v := v.(type) {
case map[string]ice.Any:
if n == 0 {
list := []string{"{"}
kit.For(v, func(k string, v ice.Any) {
list = append(list, kit.Format("%q", k), nfs.DF, FormatPretty(v, 0, 0), mdb.FS)
})
list = list[:len(list)-1]
list = append(list, "}")
return strings.Join(list, "")
}
list := []string{"{", lex.NL}
kit.For(v, func(k string, v ice.Any) {
list = append(list, strings.Repeat(lex.TB, i+1), kit.Format("%q", k), nfs.DF)
if i < n && !kit.IsIn(k, mdb.META) && !strings.HasPrefix(k, "_") {
list = append(list, FormatPretty(v, i+1, n))
} else {
list = append(list, FormatPretty(v, 0, 0))
}
list = append(list, mdb.FS, lex.NL)
})
list = append(list[:len(list)-2], lex.NL)
list = append(list, strings.Repeat(lex.TB, i), "}")
return strings.Join(list, "")
case []ice.Any:
if n == 0 {
list := []string{"["}
kit.For(v, func(k string, v ice.Any) {
list = append(list, FormatPretty(v, 0, 0), mdb.FS)
})
list = list[:len(list)-1]
list = append(list, "]")
return strings.Join(list, "")
}
list := []string{"[", lex.NL}
kit.For(v, func(v ice.Any) {
list = append(list, strings.Repeat(lex.TB, i+1))
if i < n {
list = append(list, FormatPretty(v, i+1, n))
} else {
list = append(list, FormatPretty(v, 0, 0))
}
list = append(list, mdb.FS, lex.NL)
})
list = append(list[:len(list)-2], lex.NL)
list = append(list, strings.Repeat(lex.TB, i), "]")
return strings.Join(list, "")
case string:
return kit.Format(v)
return kit.Format("%q", v)
default:
return kit.Format(v)
}
}

View File

@ -28,7 +28,7 @@ func DisplayTable(m displayMessage, arg ...ice.Any) displayMessage {
return DisplayBase(m, ice.PLUGIN_TABLE_JS, arg...)
}
func DisplayTableCard(m displayMessage, arg ...ice.Any) displayMessage {
return DisplayTable(m, "style", "card")
return DisplayTable(m, STYLE, "card")
}
func DisplayStory(m displayMessage, file string, arg ...ice.Any) displayMessage {
kit.If(file == "", func() { file = kit.Keys(kit.FileName(5), nfs.JS) })
@ -43,9 +43,7 @@ func DisplayStorySpide(m displayMessage, arg ...ice.Any) displayMessage {
}
func DisplayStudio(m *ice.Message, cmd ...string) displayMessage {
for i, k := range cmd {
if !strings.Contains(cmd[i], nfs.PT) {
cmd[i] = m.Prefix(k)
}
kit.If(!strings.Contains(cmd[i], nfs.PT), func() { cmd[i] = m.Prefix(k) })
}
return DisplayStory(m.Cmdy(COMMAND, cmd), "studio.js")
}

View File

@ -46,15 +46,6 @@ func Process(m *ice.Message, key string, args ice.Any, arg ...string) {
ProcessField(m, key, args, arg...)
}
}
func GetPod(m *ice.Message) string {
for _, key := range []string{ice.SPACE, ice.POD} {
if pod := m.Option(key); pod != "" {
m.Options(key, []string{}, ice.MSG_USERPOD, pod)
return pod
}
}
return ""
}
func ProcessField(m *ice.Message, cmd string, args ice.Any, arg ...string) *ice.Message {
if cmd = kit.Select(m.ActionKey(), cmd); !kit.HasPrefixList(arg, ice.RUN) {
if PodCmd(m, COMMAND, cmd) {
@ -77,8 +68,3 @@ func ProcessCommand(m *ice.Message, cmd string, args []string, arg ...string) {
m.Cmdy(cmd, arg[1:])
}
}
func ProcessRefresh(m *ice.Message, arg ...string) { m.ProcessRefresh(arg...) }
func ProcessRewrite(m *ice.Message, arg ...ice.Any) { m.ProcessRewrite(arg...) }
func ProcessHold(m *ice.Message, text ...ice.Any) { m.Process(ice.PROCESS_HOLD, text...) }
func ProcessOpen(m *ice.Message, url string) { m.Process(ice.PROCESS_OPEN, url) }

View File

@ -24,7 +24,7 @@ func _signal_process(m *ice.Message, p string, s os.Signal) {
if p == "" {
b, _ := file.ReadFile(ice.Info.PidPath)
p = string(b)
if runtime.GOOS == "windows" {
if runtime.GOOS == ice.WINDOWS {
return
}
}
@ -50,26 +50,26 @@ func init() {
Index.MergeCommands(ice.Commands{
SIGNAL: {Name: "signal signal auto listen", Help: "信号量", Actions: ice.MergeActions(ice.Actions{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
if runtime.GOOS == "windows" {
if runtime.GOOS == ice.WINDOWS {
return
}
_signal_listen(m, 1, mdb.NAME, "挂起", ice.CMD, "runtime")
_signal_listen(m, 2, mdb.NAME, "重启", ice.CMD, "exit 1")
_signal_listen(m, 3, mdb.NAME, "退出", ice.CMD, "exit 0")
_signal_listen(m, 1, mdb.NAME, START, ice.CMD, "runtime")
_signal_listen(m, 2, mdb.NAME, RESTART, ice.CMD, "exit 1")
_signal_listen(m, 3, mdb.NAME, STOP, ice.CMD, "exit 0")
}},
LISTEN: {Name: "listen signal name cmd", Help: "监听", Hand: func(m *ice.Message, arg ...string) {
LISTEN: {Name: "listen signal name cmd", Hand: func(m *ice.Message, arg ...string) {
_signal_listen(m, kit.Int(m.Option(SIGNAL)), arg...)
}},
HAPPEN: {Name: "happen signal", Help: "触发", Hand: func(m *ice.Message, arg ...string) {
_signal_action(m, m.Option(SIGNAL))
}},
RESTART: {Name: "restart pid", Help: "重启", Hand: func(m *ice.Message, arg ...string) {
RESTART: {Name: "restart pid", Hand: func(m *ice.Message, arg ...string) {
_signal_process(m, m.Option(PID), syscall.SIGINT)
}},
STOP: {Name: "stop pid", Help: "停止", Hand: func(m *ice.Message, arg ...string) {
STOP: {Name: "stop pid", Hand: func(m *ice.Message, arg ...string) {
_signal_process(m, m.Option(PID), syscall.SIGQUIT)
}},
KILL: {Name: "kill pid signal", Help: "结束", Hand: func(m *ice.Message, arg ...string) {
KILL: {Name: "kill pid signal", Hand: func(m *ice.Message, arg ...string) {
_signal_process(m, m.Option(PID), syscall.Signal(kit.Int(kit.Select("9", m.Option(SIGNAL)))))
}},
}, mdb.HashAction(mdb.SHORT, SIGNAL, mdb.FIELD, "time,signal,name,cmd", mdb.ACTION, HAPPEN), mdb.ClearOnExitHashAction()), Hand: func(m *ice.Message, arg ...string) {

View File

@ -36,14 +36,14 @@ func init() {
mdb.PRUNES: {Hand: func(m *ice.Message, arg ...string) { mdb.HashPrunesValue(m, mdb.COUNT, "0") }},
mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) {
switch mdb.HashInputs(m, arg); arg[0] {
case "count":
case mdb.COUNT:
m.Push(arg[0], "-1")
case "cmd":
case ice.CMD:
m.Push(arg[0], "cli.procstat insert")
}
}},
HAPPEN: {Hand: func(m *ice.Message, arg ...string) { _timer_action(m, time.Now(), arg...) }},
RESTART: {Name: "restart count=3", Hand: func(m *ice.Message, arg ...string) { mdb.HashModify(m, m.OptionSimple(mdb.HashShort(m)), arg) }},
}, mdb.HashAction(mdb.SHORT, "name", mdb.FIELD, "time,hash,name,delay,interval,count,cmd", TICK, "1s"))},
}, mdb.HashAction(mdb.SHORT, mdb.NAME, mdb.FIELD, "time,hash,name,delay,interval,count,cmd", TICK, "1s"))},
})
}

View File

@ -107,9 +107,9 @@ func init() {
SPLIT: {Name: "split path key auto", Help: "分词", Hand: func(m *ice.Message, arg ...string) {
if len(arg) == 0 || strings.HasSuffix(arg[0], nfs.PS) {
m.Cmdy(nfs.DIR, arg)
return
}
} else {
m.Echo(kit.Format(_split_list(m, arg[0], kit.Split(kit.Join(arg[1:]))...)))
}
}},
})
}

View File

@ -13,12 +13,7 @@ import (
"shylinux.com/x/toolkits/logs"
)
type Log struct {
p string
l string
s string
}
type Log struct{ p, l, s string }
type Frame struct{ p chan *Log }
func (f *Frame) Begin(m *ice.Message, arg ...string) {

View File

@ -20,10 +20,11 @@ func init() {
m.Cmd(nfs.CAT, path.Join(ice.VAR_LOG, "watch.log"), func(text string) {
ls := kit.Split(text)
m.Push(mdb.TIME, ls[0]+lex.SP+ls[1]).Push(mdb.ID, ls[2]).Push(nfs.SOURCE, kit.Slice(ls, -1)[0])
m.Push(ctx.SHIP, ls[3]).Push(ctx.ACTION, ls[4]).Push(nfs.CONTENT, kit.Join(kit.Slice(ls, 5, -1), lex.SP))
m.Push(ctx.SHIP, ls[3]).Push("operate", ls[4]).Push(nfs.CONTENT, kit.Join(kit.Slice(ls, 5, -1), lex.SP))
stats[ls[4]]++
})
m.StatusTimeCount(stats)
m.Action("filter:text")
}},
})
}

View File

@ -111,7 +111,7 @@ func _hash_export(m *ice.Message, prefix, chain, file string) {
}
func _hash_import(m *ice.Message, prefix, chain, file string) {
defer Lock(m, prefix, chain)()
f, e := ice.Info.OpenFile(m, kit.Keys(file, JSON))
f, e := ice.Info.Open(m, kit.Keys(file, JSON))
if os.IsNotExist(e) {
return
}
@ -140,7 +140,8 @@ const (
const HASH = "hash"
func HashAction(arg ...Any) ice.Actions {
return ice.Actions{ice.CTX_INIT: AutoConfig(append(kit.List(FIELD, HASH_FIELD), arg...)...),
return ice.Actions{
ice.CTX_INIT: AutoConfig(append(kit.List(FIELD, HASH_FIELD), arg...)...),
ice.CTX_EXIT: {Hand: func(m *ice.Message, arg ...string) { HashSelectClose(m) }},
INPUTS: {Hand: func(m *ice.Message, arg ...string) { HashInputs(m, arg) }},
@ -165,8 +166,8 @@ func ClearOnExitHashAction() ice.Actions {
}
func ExportHashAction() ice.Actions {
return ice.Actions{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { HashImport(m, arg) }},
ice.CTX_EXIT: {Hand: func(m *ice.Message, arg ...string) { HashExport(m, arg) }},
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { HashImport(m, arg) }},
}
}
@ -187,7 +188,6 @@ func HashField(m *ice.Message) string {
return m.Option(FIELD)
}
return kit.Select(HASH_FIELD, Config(m, FIELD))
// return kit.Select(HASH_FIELD, Config(m, FIELD), Config(m, FIELDS))
}
func HashInputs(m *ice.Message, arg ...Any) *ice.Message {
return m.Cmdy(INPUTS, m.PrefixKey(), "", HASH, arg)
@ -252,17 +252,12 @@ func HashSelectUpdate(m *ice.Message, key string, cb Any) *ice.Message {
}
func HashSelectDetail(m *ice.Message, key string, cb Any) (has bool) {
defer RLock(m, m.PrefixKey())()
Richs(m, m.PrefixKey(), nil, key, func(key string, value Map) {
_mdb_select(m, cb, key, value, nil, nil)
has = true
})
Richs(m, m.PrefixKey(), nil, key, func(key string, value Map) { _mdb_select(m, cb, key, value, nil, nil); has = true })
return
}
func HashSelectDetails(m *ice.Message, key string, cb func(Map) bool) Map {
val := kit.Dict()
HashSelectDetail(m, key, func(value Map) {
kit.If(cb(value), func() { kit.For(value, func(k string, v Any) { val[k] = v }) })
})
HashSelectDetail(m, key, func(value Map) { kit.If(cb(value), func() { kit.For(value, func(k string, v Any) { val[k] = v }) }) })
return val
}
func HashSelectField(m *ice.Message, key string, field string) (value string) {
@ -329,9 +324,6 @@ func Richs(m *ice.Message, prefix string, chain Any, raw Any, cb Any) (res Map)
}
func Rich(m *ice.Message, prefix string, chain Any, data Any) string {
cache := Confm(m, prefix, chain)
if cache == nil {
cache = kit.Data()
m.Confv(prefix, chain, cache)
}
kit.If(cache == nil, func() { cache = kit.Data(); m.Confv(prefix, chain, cache) })
return miss.Rich(path.Join(prefix, kit.Keys(chain)), cache, data)
}

View File

@ -10,7 +10,7 @@ import (
type configMessage interface {
Option(key string, arg ...Any) string
PrefixKey(...string) string
PrefixKey() string
Confv(...Any) Any
}
@ -21,10 +21,7 @@ func getLock(m configMessage, arg ...string) *task.Lock {
key := kit.Select(m.PrefixKey(), kit.Keys(arg))
defer _lock.Lock()()
l, ok := _locks[key]
if !ok {
l = &task.Lock{}
_locks[key] = l
}
kit.If(!ok, func() { l = &task.Lock{}; _locks[key] = l })
return l
}
func Lock(m configMessage, arg ...string) func() { return getLock(m, arg...).Lock() }
@ -34,9 +31,7 @@ func Config(m configMessage, key string, arg ...Any) string {
return kit.Format(Configv(m, key, arg...))
}
func Configv(m configMessage, key string, arg ...Any) Any {
if len(arg) > 0 {
Confv(m, m.PrefixKey(), kit.Keym(key), arg[0])
}
kit.If(len(arg) > 0, func() { Confv(m, m.PrefixKey(), kit.Keym(key), arg[0]) })
return Confv(m, m.PrefixKey(), kit.Keym(key))
}
func Confv(m configMessage, arg ...Any) Any {
@ -56,9 +51,7 @@ func Conf(m configMessage, arg ...Any) string {
}
func Confm(m configMessage, key string, sub Any, cbs ...Any) Map {
val := m.Confv(key, sub)
if len(cbs) > 0 {
kit.For(val, cbs[0])
}
kit.If(len(cbs) > 0, func() { kit.For(val, cbs[0]) })
value, _ := val.(Map)
return value
}
@ -66,7 +59,7 @@ func Confm(m configMessage, key string, sub Any, cbs ...Any) Map {
var cache = sync.Map{}
func Cache(m *ice.Message, key string, add func() Any) Any {
if key = m.PrefixKey(key); add == nil {
if key = kit.Keys(m.PrefixKey(), key); add == nil {
cache.Delete(key)
return nil
}

View File

@ -94,6 +94,7 @@ const (
SOURCE = "_source"
TARGET = "_target"
IMPORTANT = "important"
)
const (
INPUTS = "inputs"
@ -263,19 +264,19 @@ func AutoConfig(arg ...Any) *ice.Action {
}
func ImportantZoneAction(arg ...Any) ice.Actions {
return ice.MergeActions(ice.Actions{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { Config(m, "important", ice.TRUE) }},
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { Config(m, IMPORTANT, ice.TRUE) }},
}, ZoneAction(arg...))
}
func ImportantHashAction(arg ...Any) ice.Actions {
return ice.MergeActions(ice.Actions{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { Config(m, "important", ice.TRUE) }},
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { Config(m, IMPORTANT, ice.TRUE) }},
}, HashAction(arg...))
}
func saveImportant(m *ice.Message, key, sub string, arg ...string) {
if m.Option("skip.important") == ice.TRUE {
return
}
kit.If(m.Conf(key, kit.Keys(META, "important")) == ice.TRUE, func() { ice.SaveImportant(m, arg...) })
kit.If(m.Conf(key, kit.Keys(META, IMPORTANT)) == ice.TRUE, func() { ice.SaveImportant(m, arg...) })
}
func ToMaps(value Map) Maps {
res := Maps{}

View File

@ -11,10 +11,7 @@ func init() { Index.MergeCommands(ice.Commands{RENDER: {Help: "渲染", Actions:
func RenderAction(arg ...ice.Any) ice.Actions {
return ice.MergeActions(ice.Actions{ice.CTX_INIT: AutoConfig(SHORT, TYPE, FIELD, "time,type,name,text", arg),
CREATE: {Name: "create type name text", Hand: func(m *ice.Message, arg ...string) {
Config(m, SHORT, TYPE)
HashCreate(m)
}},
CREATE: {Name: "create type name text", Hand: func(m *ice.Message, arg ...string) { Config(m, SHORT, TYPE); HashCreate(m) }},
SELECT: {Name: "select type name text auto create", Hand: func(m *ice.Message, arg ...string) {
if len(arg) < 2 || arg[0] == "" {
HashSelect(m, arg...)

View File

@ -94,7 +94,7 @@ func _zone_export(m *ice.Message, prefix, chain, file string) {
}
func _zone_import(m *ice.Message, prefix, chain, file string) {
defer Lock(m, prefix, chain)()
f, e := ice.Info.OpenFile(m, kit.Keys(file, CSV))
f, e := ice.Info.Open(m, kit.Keys(file, CSV))
if os.IsNotExist(e) {
return
}

View File

@ -120,9 +120,10 @@ func init() {
if len(arg) == 0 || strings.HasSuffix(arg[0], PS) {
m.Cmdy(DIR, arg)
} else {
if arg[0] == "action" {
if arg[0] == ice.ACTION {
m.Cmdy(DIR, arg)
} else if !Show(m, arg[0]) {
} else {
// } else if !Show(m, arg[0]) {
_cat_list(m.Logs(FIND, m.OptionSimple(DIR_ROOT), FILE, arg[0]), arg[0])
}
}
@ -132,8 +133,8 @@ func init() {
type templateMessage interface {
Optionv(key string, arg ...ice.Any) ice.Any
PrefixKey(...string) string
Cmdx(...ice.Any) string
PrefixKey() string
}
func Template(m templateMessage, p string, arg ...ice.Any) string {
@ -164,9 +165,7 @@ func Open(m *ice.Message, p string, cb ice.Any) {
if p == "" {
return
} else if strings.HasSuffix(p, PS) {
if p == PS {
p = ""
}
kit.If(p == PS, func() { p = "" })
if ls, e := ReadDir(m, p); !m.Warn(e) {
switch cb := cb.(type) {
case func([]os.FileInfo):
@ -174,9 +173,7 @@ func Open(m *ice.Message, p string, cb ice.Any) {
case func(os.FileInfo):
kit.For(ls, cb)
case func(io.Reader, string):
kit.For(ls, func(s os.FileInfo) {
kit.If(!s.IsDir(), func() { Open(m, path.Join(p, s.Name()), cb) })
})
kit.For(ls, func(s os.FileInfo) { kit.If(!s.IsDir(), func() { Open(m, path.Join(p, s.Name()), cb) }) })
default:
m.ErrorNotImplement(cb)
}

View File

@ -145,7 +145,12 @@ const (
USR_LOCAL_WORK = ice.USR_LOCAL_WORK
SRC_DOCUMENT = ice.SRC_DOCUMENT
REQUIRE = "/require/"
VOLCANOS = "/volcanos/"
INTSHELL = "/intshell/"
PATHNAME = "pathname"
FILENAME = "filename"
USR_ICONS_ICEBERGS = "usr/icons/icebergs.jpg"
TYPE_ALL = "all"
TYPE_BIN = "bin"
@ -175,16 +180,16 @@ const DIR = "dir"
func init() {
Index.MergeCommands(ice.Commands{
DIR: {Name: "dir path auto upload finder", Icon: "usr/icons/dir.png", Help: "目录", Actions: ice.Actions{
DIR: {Name: "dir path auto upload app", Icon: "usr/icons/dir.png", Help: "目录", Actions: ice.Actions{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
aaa.White(m, ice.SRC, ice.BIN, ice.USR)
aaa.Black(m, ice.USR_LOCAL)
}}, mdb.UPLOAD: {},
"finder": {Help: "本机", Hand: func(m *ice.Message, arg ...string) { m.Cmd("cli.system", "opens", "Finder.app") }},
}},
ice.APP: {Help: "本机", Hand: func(m *ice.Message, arg ...string) { m.Cmd("cli.system", "opens", "Finder.app") }},
TRASH: {Hand: func(m *ice.Message, arg ...string) { m.Cmd(TRASH, mdb.CREATE, m.Option(PATH)) }},
mdb.SHOW: {Help: "预览", Hand: func(m *ice.Message, arg ...string) {
Show(m.ProcessInner(), path.Join(m.Option(DIR_ROOT), m.Option(PATH)))
}},
}}, mdb.UPLOAD: {},
}, Hand: func(m *ice.Message, arg ...string) {
root, dir := kit.Select(PWD, m.Option(DIR_ROOT)), kit.Select(PWD, arg, 0)
kit.If(strings.HasPrefix(dir, PS), func() { root = "" })
@ -235,17 +240,6 @@ func Dir(m *ice.Message, field string) *ice.Message {
m.Copy(m.Cmd(DIR, PWD, kit.Dict(DIR_TYPE, TYPE_CAT)).Sort(field))
return m
}
func Show(m *ice.Message, file string) bool {
switch strings.ToLower(kit.Ext(file)) {
case "png", "jpg":
m.EchoImages("/share/local/" + file)
case "mp4", "mov":
m.EchoVideos("/share/local/" + file)
default:
return false
}
return true
}
func DirDeepAll(m *ice.Message, root, dir string, cb func(ice.Maps), arg ...string) *ice.Message {
m.Options(DIR_TYPE, CAT, DIR_ROOT, root, DIR_DEEP, ice.TRUE)
defer m.Options(DIR_TYPE, "", DIR_ROOT, "", DIR_DEEP, "")
@ -255,3 +249,18 @@ func DirDeepAll(m *ice.Message, root, dir string, cb func(ice.Maps), arg ...stri
return msg.Table(cb)
}
}
func Show(m *ice.Message, file string) bool {
switch strings.ToLower(kit.Ext(file)) {
case "png", "jpg":
m.EchoImages("/share/local/" + file)
case "mp4", "mov":
m.EchoVideos("/share/local/" + file)
default:
if IsSourceFile(m, kit.Ext(file)) {
m.Cmdy(CAT, file)
} else {
return false
}
}
return true
}

View File

@ -17,13 +17,6 @@ const PACK = "pack"
func init() {
Index.MergeCommands(ice.Commands{
PACK: {Name: "pack path auto upload create", Help: "文件系统", Actions: ice.Actions{
mdb.CREATE: {Name: "create path*=src/hi/hi.txt text*=hello", Hand: func(m *ice.Message, arg ...string) {
OptionFiles(m, PackFile)
Create(m, m.Option(PATH), func(w io.Writer, p string) {
Save(m, w, m.Option(mdb.TEXT), func(n int) { m.Logs(LOAD, FILE, p, SIZE, n) })
})
}},
mdb.REMOVE: {Hand: func(m *ice.Message, arg ...string) { PackFile.Remove(path.Clean(m.Option(PATH))) }},
mdb.SEARCH: {Hand: func(m *ice.Message, arg ...string) {
if arg[0] == mdb.FOREACH && arg[1] != "" {
m.Cmd(DIR, SRC, PATH, kit.Dict(DIR_REG, arg[1], DIR_DEEP, ice.TRUE, DIR_TYPE, CAT), func(value ice.Maps) {
@ -38,6 +31,13 @@ func init() {
})
}
}},
mdb.CREATE: {Name: "create path*=src/hi/hi.txt text*=hello", Hand: func(m *ice.Message, arg ...string) {
OptionFiles(m, PackFile)
Create(m, m.Option(PATH), func(w io.Writer, p string) {
Save(m, w, m.Option(mdb.TEXT), func(n int) { m.Logs(LOAD, FILE, p, SIZE, n) })
})
}},
mdb.REMOVE: {Hand: func(m *ice.Message, arg ...string) { PackFile.Remove(path.Clean(m.Option(PATH))) }},
mdb.IMPORT: {Hand: func(m *ice.Message, arg ...string) {
OptionFiles(m, DiskFile)
Open(m, path.Join(m.Option(PATH), m.Option(FILE)), func(r io.Reader, p string) {
@ -68,11 +68,11 @@ func init() {
})
}
var PackFile = file.NewPackFile()
var DiskFile = file.NewDiskFile()
var PackFile = file.NewPackFile()
func init() { file.Init(OptionFiles(ice.Pulse, DiskFile, PackFile)) }
func init() { ice.Info.OpenFile = OpenFile }
func init() { ice.Info.Open = OpenFile }
type optionMessage interface {
Optionv(key string, arg ...ice.Any) ice.Any

View File

@ -30,10 +30,6 @@ const TRASH = "trash"
func init() {
Index.MergeCommands(ice.Commands{
TRASH: {Name: "trash hash auto prunes", Help: "回收站", Actions: ice.MergeActions(ice.Actions{
mdb.REVERT: {Hand: func(m *ice.Message, arg ...string) {
Rename(m, m.Option(FILE), m.Option(FROM))
mdb.HashRemove(m, m.OptionSimple(mdb.HASH))
}},
mdb.CREATE: {Hand: func(m *ice.Message, arg ...string) {
_trash_create(m, kit.Paths(m.Option(FROM)))
}},
@ -41,6 +37,10 @@ func init() {
Remove(m, m.Option(FILE))
mdb.HashRemove(m, m.OptionSimple(mdb.HASH))
}},
mdb.REVERT: {Hand: func(m *ice.Message, arg ...string) {
Rename(m, m.Option(FILE), m.Option(FROM))
mdb.HashRemove(m, m.OptionSimple(mdb.HASH))
}},
mdb.PRUNES: {Hand: func(m *ice.Message, arg ...string) {
mdb.HashPrunes(m, nil).Table(func(value ice.Maps) { Remove(m, value[FILE]) })
}},

View File

@ -11,11 +11,11 @@ const ADMIN = "admin"
func init() {
Index.MergeCommands(ice.Commands{
ADMIN: {Name: ADMIN, Help: "管理", Hand: func(m *ice.Message, arg ...string) {
ADMIN: {Name: "admin index list", Help: "管理", Hand: func(m *ice.Message, arg ...string) {
args := []string{}
kit.If(len(arg) == 0, func() { arg = append(arg, SPACE, DOMAIN) })
kit.For(arg[1:], func(v string) { args = append(args, ice.ARG, v) })
m.Cmdy(SPIDE, ice.OPS, SPIDE_RAW, http.MethodGet, CHAT_CMD+arg[0]+"?debug=true", args)
m.Cmdy(SPIDE, ice.OPS, SPIDE_RAW, http.MethodGet, CHAT_CMD+arg[0], args)
}},
})
}

47
base/web/basic.go Normal file
View File

@ -0,0 +1,47 @@
package web
import (
"encoding/base64"
"strings"
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/aaa"
"shylinux.com/x/icebergs/base/mdb"
kit "shylinux.com/x/toolkits"
)
func init() {
Index.MergeCommands(ice.Commands{
"/basic/check": {Hand: func(m *ice.Message, arg ...string) {
kit.For(m.R.Header, func(key string, value []string) { m.Debug("what %v %v", key, value) })
if BasicSess(m); m.Option(ice.MSG_USERNAME) == "" {
BasicCheck(m, "请输入账号密码")
}
}},
"/basic/login": {Hand: func(m *ice.Message, arg ...string) { RenderMain(m) }},
"/basic/auths": {Hand: func(m *ice.Message, arg ...string) {
kit.If(m.R.URL.Query().Get(ice.MSG_SESSID), func(p string) { RenderCookie(m, m.Option(ice.MSG_SESSID, p)) })
RenderRedirect(m, m.R.URL.Query().Get("redirect_uri"))
}},
})
}
func BasicSess(m *ice.Message) {
m.Options(ice.MSG_USERWEB, _serve_domain(m))
m.Options(ice.MSG_SESSID, kit.Select(m.Option(ice.MSG_SESSID), m.Option(CookieName(m.Option(ice.MSG_USERWEB)))))
aaa.SessCheck(m, m.Option(ice.MSG_SESSID))
}
func BasicCheck(m *ice.Message, realm string) bool {
switch ls := kit.Split(m.R.Header.Get(Authorization)); kit.Select("", ls, 0) {
case Basic:
if buf, err := base64.StdEncoding.DecodeString(kit.Select("", ls, 1)); !m.Warn(err) {
if ls := strings.SplitN(string(buf), ":", 2); !m.Warn(len(ls) < 2) {
if msg := m.Cmd(TOKEN, ls[1]); !m.Warn(msg.Time() > msg.Append(mdb.TIME)) {
return true
}
}
}
}
m.W.Header().Add("WWW-Authenticate", kit.Format(`Basic realm="%s"`, realm))
m.RenderStatusUnauthorized()
return false
}

View File

@ -5,7 +5,6 @@ import (
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/aaa"
"shylinux.com/x/icebergs/base/ctx"
"shylinux.com/x/icebergs/base/gdb"
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/nfs"
@ -54,9 +53,7 @@ func init() {
}},
SERVE_START: {Hand: func(m *ice.Message, arg ...string) { gdb.Go(m, _broad_serve) }},
SERVE: {Name: "serve port=9020 host", Hand: func(m *ice.Message, arg ...string) { gdb.Go(m, _broad_serve) }},
OPEN: {Hand: func(m *ice.Message, arg ...string) {
ctx.ProcessOpen(m, Domain(m.Option(tcp.HOST), m.Option(tcp.PORT)))
}},
OPEN: {Hand: func(m *ice.Message, arg ...string) { m.ProcessOpen(Domain(m.Option(tcp.HOST), m.Option(tcp.PORT))) }},
tcp.SEND: {Hand: func(m *ice.Message, arg ...string) { _broad_send(m, "", "", "", "", arg...) }},
}, mdb.HashAction(mdb.SHORT, "host,port", mdb.FIELD, "time,hash,type,name,host,port", mdb.ACTION, OPEN), mdb.ClearOnExitHashAction())},
})

View File

@ -112,13 +112,13 @@ const CACHE = "cache"
func init() {
Index.MergeCommands(ice.Commands{
CACHE: {Name: "cache hash auto write catch upload download", Help: "缓存池", Actions: ice.MergeActions(ice.Actions{
WATCH: {Name: "watch hash* path*", Help: "释放", Hand: func(m *ice.Message, arg ...string) {
WATCH: {Name: "watch hash* path*", Hand: func(m *ice.Message, arg ...string) {
_cache_watch(m, m.Option(mdb.HASH), m.Option(nfs.PATH))
}},
WRITE: {Name: "write type name* text*", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
WRITE: {Name: "write type name* text*", Hand: func(m *ice.Message, arg ...string) {
_cache_save(m, m.Option(mdb.TYPE), m.Option(mdb.NAME), m.Option(mdb.TEXT))
}},
CATCH: {Name: "catch path* type", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
CATCH: {Name: "catch path* type", Hand: func(m *ice.Message, arg ...string) {
file, size := _cache_catch(m, m.Option(nfs.PATH))
_cache_save(m, m.Option(mdb.TYPE), m.Option(nfs.PATH), "", file, size)
}},
@ -133,7 +133,7 @@ func init() {
}
}},
ice.RENDER_DOWNLOAD: {Hand: func(m *ice.Message, arg ...string) {
m.Echo(_share_link(m, kit.Select(arg[0], arg, 1), ice.POD, m.Option(ice.MSG_USERPOD), "filename", kit.Select("", arg[0], len(arg) > 1)))
m.Echo(_share_link(m, kit.Select(arg[0], arg, 1), ice.POD, m.Option(ice.MSG_USERPOD), nfs.FILENAME, kit.Select("", arg[0], len(arg) > 1)))
}},
nfs.PS: {Hand: func(m *ice.Message, arg ...string) {
mdb.HashSelectDetail(m, arg[0], func(value ice.Map) {

View File

@ -11,7 +11,7 @@ const COUNT = "count"
func init() {
Index.MergeCommands(ice.Commands{
COUNT: &ice.Command{Name: "count hash auto", Help: "计数", Actions: ice.MergeActions(ice.Actions{
COUNT: &ice.Command{Name: "count hash auto prunes", Help: "计数", Actions: ice.MergeActions(ice.Actions{
mdb.SEARCH: {Hand: func(m *ice.Message, arg ...string) {
if mdb.IsSearchPreview(m, arg) {
count, limit, list := 0, 5, map[string]bool{}
@ -46,7 +46,7 @@ func init() {
mdb.HashSelectUpdate(m, mdb.HashCreate(m), func(value ice.Map) { value[mdb.COUNT] = kit.Int(value[mdb.COUNT]) + 1 })
}},
}, ctx.CmdAction(), mdb.HashAction(mdb.LIMIT, 1000, mdb.LEAST, 500, mdb.SHORT, "type,name", mdb.FIELD, "time,hash,count,type,name,text")), Hand: func(m *ice.Message, arg ...string) {
mdb.HashSelect(m, arg...).Sort("type,name,text", "str", "str", "str")
mdb.HashSelect(m, arg...).Sort("type,name,text")
}},
})
}

View File

@ -66,11 +66,11 @@ func _dream_start(m *ice.Message, name string) {
m.Info("already exists %v", name)
return
}
m.Sleep("1s")
m.Sleep300ms()
}
}
defer ToastProcess(m)()
defer m.Sleep("1s")
defer m.Sleep300ms()
m.Options(cli.CMD_DIR, kit.Path(p), cli.CMD_ENV, kit.EnvList(kit.Simple(
cli.CTX_OPS, Domain(tcp.LOCALHOST, m.Cmdv(SERVE, tcp.PORT)), cli.CTX_LOG, ice.VAR_LOG_BOOT_LOG, cli.CTX_PID, ice.VAR_LOG_ICE_PID,
cli.PATH, cli.BinPath(p, ""), cli.USER, ice.Info.Username,
@ -84,9 +84,9 @@ func _dream_start(m *ice.Message, name string) {
}
func _dream_binary(m *ice.Message, p string) {
if bin := path.Join(m.Option(cli.CMD_DIR), ice.BIN_ICE_BIN); nfs.Exists(m, bin) {
return
} else if kit.IsUrl(p) {
GoToast(m, "download", func(toast func(string, int, int)) (list []string) {
GoToast(m, DOWNLOAD, func(toast func(string, int, int)) (list []string) {
begin := time.Now()
SpideSave(m, bin, kit.MergeURL(p, cli.GOOS, runtime.GOOS, cli.GOARCH, runtime.GOARCH), func(count, total, value int) {
cost := time.Now().Sub(begin)
@ -101,8 +101,8 @@ func _dream_binary(m *ice.Message, p string) {
}
func _dream_template(m *ice.Message, p string) {
kit.For([]string{
ice.LICENSE, ice.MAKEFILE, ice.README_MD, ice.GO_MOD, ice.GO_SUM,
ice.SRC_MAIN_SH, ice.SRC_MAIN_SHY, ice.SRC_MAIN_GO, ice.SRC_MAIN_JS,
ice.README_MD, ice.MAKEFILE, ice.LICENSE, ice.GO_MOD, ice.GO_SUM,
ice.SRC_MAIN_SHY, ice.SRC_MAIN_SH, ice.SRC_MAIN_GO, ice.SRC_MAIN_JS,
ice.ETC_MISS_SH, ice.ETC_INIT_SHY, ice.ETC_EXIT_SHY,
}, func(file string) {
if nfs.Exists(m, kit.Path(m.Option(cli.CMD_DIR), file)) {
@ -119,12 +119,12 @@ func _dream_template(m *ice.Message, p string) {
const (
DREAM_CREATE = "dream.create"
DREAM_REMOVE = "dream.remove"
DREAM_START = "dream.start"
DREAM_STOP = "dream.stop"
DREAM_OPEN = "dream.open"
DREAM_CLOSE = "dream.close"
DREAM_TRASH = "dream.trash"
DREAM_REMOVE = "dream.remove"
DREAM_INPUTS = "dream.inputs"
DREAM_TABLES = "dream.tables"
@ -134,7 +134,13 @@ const DREAM = "dream"
func init() {
Index.MergeCommands(ice.Commands{
DREAM: {Name: "dream name@key auto create origin startall stopall build cat cmd", Icon: "usr/icons/Launchpad.png", Help: "梦想家", Actions: ice.MergeActions(ice.Actions{
DREAM: {Name: "dream name@key auto create repos startall stopall build cmd cat", Icon: "usr/icons/Launchpad.png", Help: "梦想家", Actions: ice.MergeActions(ice.Actions{
ctx.CONFIG: {Hand: func(m *ice.Message, arg ...string) {
for _, cmd := range kit.Reverse(arg) {
m.Cmd(gdb.EVENT, gdb.LISTEN, gdb.EVENT, DREAM_TABLES, ice.CMD, cmd)
m.Cmd(gdb.EVENT, gdb.LISTEN, gdb.EVENT, DREAM_ACTION, ice.CMD, cmd)
}
}},
mdb.SEARCH: {Hand: func(m *ice.Message, arg ...string) {
if mdb.IsSearchPreview(m, arg) {
m.Cmds("", func(value ice.Maps) { m.PushSearch(mdb.TEXT, m.MergePod(value[mdb.NAME]), value) })
@ -159,77 +165,16 @@ func init() {
gdb.Event(m, DREAM_INPUTS, arg)
}
}},
nfs.CAT: {Name: "cat file*", Help: "文件", Hand: func(m *ice.Message, arg ...string) {
mdb.HashSelect(m.Spawn()).Table(func(value ice.Maps) {
m.Push(mdb.NAME, value[mdb.NAME])
m.Push(mdb.TEXT, m.Cmdx(SPACE, value[mdb.NAME], nfs.CAT, m.Option(nfs.FILE)))
})
m.StatusTimeCount()
}},
ice.CMD: {Name: "cmd cmd*", Help: "命令", Hand: func(m *ice.Message, arg ...string) {
GoToast(m, "", func(toast func(string, int, int)) []string {
msg := mdb.HashSelect(m.Spawn())
msg.Table(func(index int, value ice.Maps) {
toast(value[mdb.NAME], index, msg.Length())
m.Push(mdb.NAME, value[mdb.NAME])
m.Push(mdb.TEXT, m.Cmdx(SPACE, value[mdb.NAME], kit.Split(m.Option("cmd"))))
})
return nil
})
m.StatusTimeCount()
}},
mdb.CREATE: {Name: "create name*=hi repos binary template", Hand: func(m *ice.Message, arg ...string) {
m.OptionDefault(mdb.ICON, "usr/icons/icebergs.jpg")
m.OptionDefault(mdb.ICON, nfs.USR_ICONS_ICEBERGS)
m.Option(nfs.REPOS, kit.Select("", kit.Slice(kit.Split(m.Option(nfs.REPOS)), -1), 0))
kit.If(!strings.Contains(m.Option(mdb.NAME), "-") || !strings.HasPrefix(m.Option(mdb.NAME), "20"), func() { m.Option(mdb.NAME, m.Time("20060102-")+m.Option(mdb.NAME)) })
if mdb.HashCreate(m); !m.IsCliUA() {
_dream_start(m, m.OptionDefault(mdb.NAME, path.Base(m.Option(nfs.REPOS))))
}
}},
cli.BUILD: {Hand: func(m *ice.Message, arg ...string) {
GoToast(m, "", func(toast func(string, int, int)) []string {
msg := mdb.HashSelect(m.Spawn())
msg.Table(func(index int, value ice.Maps) {
toast(value[mdb.NAME], index, msg.Length())
m.Push(mdb.NAME, value[mdb.NAME])
m.Push(mdb.TEXT, m.Cmdx(SPACE, value[mdb.NAME], "compile", "linux"))
m.Push(mdb.NAME, value[mdb.NAME])
m.Push(mdb.TEXT, m.Cmdx(SPACE, value[mdb.NAME], "compile", "darwin"))
m.Push(mdb.NAME, value[mdb.NAME])
m.Push(mdb.TEXT, m.Cmdx(SPACE, value[mdb.NAME], "compile", "windows"))
})
return nil
})
m.StatusTimeCount()
}},
cli.START: {Hand: func(m *ice.Message, arg ...string) {
gdb.Event(m, DREAM_START, arg)
_dream_start(m, m.Option(mdb.NAME))
}},
cli.STOP: {Hand: func(m *ice.Message, arg ...string) {
gdb.Event(m, DREAM_STOP, arg)
m.Cmd(SPACE, mdb.MODIFY, m.OptionSimple(mdb.NAME), mdb.STATUS, cli.STOP)
m.Go(func() { m.Cmd(SPACE, m.Option(mdb.NAME), ice.EXIT) })
m.Sleep30ms()
}},
nfs.TRASH: {Hand: func(m *ice.Message, arg ...string) {
gdb.Event(m, DREAM_TRASH, arg)
nfs.Trash(m, path.Join(ice.USR_LOCAL_WORK, m.Option(mdb.NAME)))
}},
DREAM_CLOSE: {Hand: func(m *ice.Message, arg ...string) {
if m.Option(cli.DAEMON) == ice.OPS && m.Cmdv(SPACE, m.Option(mdb.NAME), mdb.STATUS) != cli.STOP {
m.Go(func() { m.Sleep300ms(DREAM, cli.START, m.OptionSimple(mdb.NAME)) })
}
}},
DREAM_TABLES: {Hand: func(m *ice.Message, arg ...string) {
kit.Switch(m.Option(mdb.TYPE), []string{WORKER, SERVER}, func() { m.PushButton(OPEN, ice.MAIN) })
}},
ice.MAIN: {Name: "main index", Help: "首页", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(SPACE, m.Option(mdb.NAME), SPACE, ice.MAIN, m.Option(ctx.INDEX))
}},
OPEN: {Hand: func(m *ice.Message, arg ...string) { ctx.ProcessOpen(m, m.MergePod(m.Option(mdb.NAME))) }},
"origin": {Name: "origin", Help: "仓库", Hand: func(m *ice.Message, arg ...string) {
m.ProcessOpen(m.MergePodCmd("", "web.code.git.search", "repos", "repos"))
nfs.REPOS: {Help: "仓库", Hand: func(m *ice.Message, arg ...string) {
m.ProcessOpen(m.MergePodCmd("", CODE_GIT_SEARCH, nfs.REPOS, nfs.REPOS))
}},
"startall": {Name: "startall name", Help: "启动", Hand: func(m *ice.Message, arg ...string) {
reg, err := regexp.Compile(m.Option(mdb.NAME))
@ -275,20 +220,73 @@ func init() {
return nil
})
}},
"button": {Hand: func(m *ice.Message, arg ...string) {
for _, cmd := range kit.Reverse(arg) {
m.Cmd(gdb.EVENT, gdb.LISTEN, gdb.EVENT, DREAM_TABLES, ice.CMD, cmd)
m.Cmd(gdb.EVENT, gdb.LISTEN, gdb.EVENT, DREAM_ACTION, ice.CMD, cmd)
cli.BUILD: {Hand: func(m *ice.Message, arg ...string) {
GoToast(m, "", func(toast func(string, int, int)) []string {
msg := mdb.HashSelect(m.Spawn())
msg.Table(func(index int, value ice.Maps) {
toast(value[mdb.NAME], index, msg.Length())
m.Push(mdb.NAME, value[mdb.NAME])
m.Push(mdb.TEXT, m.Cmdx(SPACE, value[mdb.NAME], "compile", cli.LINUX))
m.Push(mdb.NAME, value[mdb.NAME])
m.Push(mdb.TEXT, m.Cmdx(SPACE, value[mdb.NAME], "compile", cli.DARWIN))
m.Push(mdb.NAME, value[mdb.NAME])
m.Push(mdb.TEXT, m.Cmdx(SPACE, value[mdb.NAME], "compile", cli.WINDOWS))
})
return nil
})
m.StatusTimeCount()
}},
nfs.CAT: {Name: "cat file*", Help: "文件", Hand: func(m *ice.Message, arg ...string) {
mdb.HashSelect(m.Spawn()).Table(func(value ice.Maps) {
m.Push(mdb.NAME, value[mdb.NAME])
m.Push(mdb.TEXT, m.Cmdx(SPACE, value[mdb.NAME], nfs.CAT, m.Option(nfs.FILE)))
})
m.StatusTimeCount()
}},
ice.CMD: {Name: "cmd cmd*", Help: "命令", Hand: func(m *ice.Message, arg ...string) {
GoToast(m, "", func(toast func(string, int, int)) []string {
msg := mdb.HashSelect(m.Spawn())
msg.Table(func(index int, value ice.Maps) {
toast(value[mdb.NAME], index, msg.Length())
m.Push(mdb.NAME, value[mdb.NAME])
m.Push(mdb.TEXT, m.Cmdx(SPACE, value[mdb.NAME], kit.Split(m.Option("cmd"))))
})
return nil
})
m.StatusTimeCount()
}},
cli.START: {Hand: func(m *ice.Message, arg ...string) {
gdb.Event(m, DREAM_START, arg)
_dream_start(m, m.Option(mdb.NAME))
}},
cli.STOP: {Hand: func(m *ice.Message, arg ...string) {
gdb.Event(m, DREAM_STOP, arg)
m.Cmd(SPACE, mdb.MODIFY, m.OptionSimple(mdb.NAME), mdb.STATUS, cli.STOP)
m.Go(func() { m.Cmd(SPACE, m.Option(mdb.NAME), ice.EXIT) })
m.Sleep30ms()
}},
nfs.TRASH: {Hand: func(m *ice.Message, arg ...string) {
gdb.Event(m, DREAM_TRASH, arg)
nfs.Trash(m, path.Join(ice.USR_LOCAL_WORK, m.Option(mdb.NAME)))
}},
ice.MAIN: {Name: "main index", Help: "首页", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(SPACE, m.Option(mdb.NAME), SPACE, ice.MAIN, m.Option(ctx.INDEX))
}},
OPEN: {Hand: func(m *ice.Message, arg ...string) { m.ProcessOpen(m.MergePod(m.Option(mdb.NAME))) }},
DREAM_CLOSE: {Hand: func(m *ice.Message, arg ...string) {
if m.Option(cli.DAEMON) == ice.OPS && m.Cmdv(SPACE, m.Option(mdb.NAME), mdb.STATUS) != cli.STOP {
m.Go(func() { m.Sleep300ms(DREAM, cli.START, m.OptionSimple(mdb.NAME)) })
}
}},
}, ctx.CmdAction(), DreamAction(), mdb.ImportantHashAction(mdb.SHORT, mdb.NAME, mdb.FIELD, "time,name,icon,repos,binary,template")), Hand: func(m *ice.Message, arg ...string) {
DREAM_TABLES: {Hand: func(m *ice.Message, arg ...string) {
kit.Switch(m.Option(mdb.TYPE), []string{WORKER, SERVER}, func() { m.PushButton(OPEN, ice.MAIN) })
}},
}, DreamAction(), ctx.CmdAction(), mdb.ImportantHashAction(mdb.SHORT, mdb.NAME, mdb.FIELD, "time,name,icon,repos,binary,template")), Hand: func(m *ice.Message, arg ...string) {
if len(arg) == 0 {
_dream_list(m)
m.RewriteAppend(func(value, key string, index int) string {
if key == "icon" {
if !kit.HasPrefix(value, nfs.PS, HTTP) {
return kit.MergeURL("/require/"+value, ice.POD, m.Appendv(mdb.NAME)[index])
}
if key == mdb.ICON {
return kit.MergeURL(ctx.FileURI(value), ice.POD, m.Appendv(mdb.NAME)[index])
}
return value
})

View File

@ -11,11 +11,16 @@ const (
CONTENT = "content"
PROFILE = "profile"
DISPLAY = "display"
VIEW = "view"
INPUT = "input"
OUTPUT = "output"
LAYOUT = "layout"
RESIZE = "resize"
)
const (
FLOAT = "float"
OUTPUT = "output"
CHROME = "chrome"
TEXT_PLAIN = "text/plain"

View File

@ -19,7 +19,7 @@ import (
type Message interface {
Option(key string, arg ...ice.Any) string
PrefixKey(...string) string
PrefixKey() string
}
func UserWeb(m Message) *url.URL { return kit.ParseURL(m.Option(ice.MSG_USERWEB)) }
@ -39,19 +39,15 @@ func AgentIs(m Message, arg ...string) bool {
return false
}
func MergeURL2(m Message, url string, arg ...ice.Any) string {
if m.Option(log.DEBUG) == ice.TRUE {
arg = append([]ice.Any{log.DEBUG, ice.TRUE}, arg)
}
if m.Option(ice.MSG_USERWEB) == "" {
return kit.MergeURL2(Domain(ice.Pulse.Cmdv(tcp.HOST, aaa.IP), ice.Pulse.Cmdv(SERVE, tcp.PORT)), url, arg...)
}
kit.If(m.Option(log.DEBUG) == ice.TRUE, func() { arg = append(arg, log.DEBUG, ice.TRUE) })
kit.If(m.Option(ice.MSG_USERWEB) == "", func() {
m.Option(ice.MSG_USERWEB, Domain(ice.Pulse.Cmdv(tcp.HOST, aaa.IP), ice.Pulse.Cmdv(SERVE, tcp.PORT)))
})
return kit.MergeURL2(m.Option(ice.MSG_USERWEB), url, arg...)
}
func MergeLink(m Message, url string, arg ...ice.Any) string {
if m.Option(log.DEBUG) == ice.TRUE {
arg = append(arg, log.DEBUG, ice.TRUE)
}
return kit.MergeURL(strings.Split(MergeURL2(m, url), mdb.QS)[0], arg...)
kit.If(m.Option(log.DEBUG) == ice.TRUE, func() { arg = append(arg, log.DEBUG, ice.TRUE) })
return kit.MergeURL(strings.Split(MergeURL2(m, url), QS)[0], arg...)
}
func ProcessPodCmd(m *ice.Message, pod, cmd string, arg ...ice.Any) {
m.ProcessOpen(m.MergePodCmd(pod, cmd, arg...))
@ -62,15 +58,15 @@ func ProcessIframe(m *ice.Message, name, link string, arg ...string) {
}, arg...)
}
func PushPodCmd(m *ice.Message, cmd string, arg ...string) {
kit.If(m.Length() > 0 && len(m.Appendv(SPACE)) == 0, func() { m.Table(func(value ice.Maps) { m.Push(SPACE, "") }) })
list := []string{}
m.Cmds(SPACE, func(value ice.Maps) {
// kit.If(kit.IsIn(value[mdb.TYPE], WORKER, SERVER), func() { list = append(list, value[mdb.NAME]) })
kit.If(kit.IsIn(value[mdb.TYPE], WORKER), func() { list = append(list, value[mdb.NAME]) })
// kit.If(kit.IsIn(value[mdb.TYPE], WORKER, SERVER), func() { list = append(list, value[mdb.NAME]) })
})
if len(list) == 0 {
return
}
kit.If(m.Length() > 0 && len(m.Appendv(SPACE)) == 0, func() { m.Table(func(value ice.Maps) { m.Push(SPACE, "") }) })
GoToast(m, "", func(toast func(string, int, int)) []string {
kit.For(list, func(index int, space string) {
toast(space, index, len(list))
@ -126,8 +122,8 @@ func Toast(m *ice.Message, text string, arg ...ice.Any) { // [title [duration [p
func toastContent(m *ice.Message, state string) string {
return kit.Join([]string{map[string]string{ice.PROCESS: "🕑", ice.FAILURE: "❌", ice.SUCCESS: "✅"}[state], state, m.ActionKey()}, " ")
}
func ToastFailure(m *ice.Message, arg ...ice.Any) { Toast(m, toastContent(m, ice.FAILURE), arg...) }
func ToastSuccess(m *ice.Message, arg ...ice.Any) { Toast(m, toastContent(m, ice.SUCCESS), arg...) }
func ToastFailure(m *ice.Message, arg ...ice.Any) { Toast(m, toastContent(m, ice.FAILURE), arg...) }
func ToastProcess(m *ice.Message, arg ...ice.Any) func() {
kit.If(len(arg) == 0, func() { arg = kit.List("", "-1") })
kit.If(len(arg) == 1, func() { arg = append(arg, "-1") })

View File

@ -32,7 +32,7 @@ func Render(m *ice.Message, cmd string, args ...ice.Any) bool {
arg := kit.Simple(args...)
kit.If(len(arg) == 0, func() { args = nil })
if cmd != "" {
if cmd != ice.RENDER_DOWNLOAD || !kit.HasPrefix(arg[0], ice.USR_VOLCANOS, ice.USR_INTSHELL, "src/template/", "usr/icons/", "usr/node_modules/") {
if cmd != ice.RENDER_DOWNLOAD || !kit.HasPrefix(arg[0], ice.USR_VOLCANOS, ice.USR_INTSHELL, ice.SRC_TEMPLATE, ice.USR_ICONS, "usr/node_modules/") {
defer func() { m.Logs("Render", cmd, args) }()
}
}
@ -60,18 +60,14 @@ func Render(m *ice.Message, cmd string, args ...ice.Any) bool {
if len(arg) > 0 { // [str [arg...]]
m.W.Write([]byte(kit.Format(arg[0], args[1:]...)))
} else {
if m.Result() == "" && m.Length() > 0 {
m.TableEcho()
}
kit.If(m.Result() == "" && m.Length() > 0, func() { m.TableEcho() })
m.W.Write([]byte(m.Result()))
}
case ice.RENDER_JSON:
RenderType(m.W, nfs.JSON, "")
m.W.Write([]byte(arg[0]))
default:
if cmd != "" && cmd != ice.RENDER_RAW {
m.Echo(kit.Format(cmd, args...))
}
kit.If(cmd != "" && cmd != ice.RENDER_RAW, func() { m.Echo(kit.Format(cmd, args...)) })
RenderType(m.W, nfs.JSON, "")
m.FormatsMeta(m.W)
}
@ -154,21 +150,12 @@ func RenderVersion(m *ice.Message) string {
}
const (
DARK = "dark"
LIGHT = "light"
BLACK = "black"
DISPLAY = "display"
RESIZE = "resize"
LAYOUT = "layout"
OUTPUT = "output"
INPUT = "input"
VIEW = "view"
CHAT = "chat"
CHAT_POD = "/chat/pod/"
CHAT_CMD = "/chat/cmd/"
CODE_GIT_SERVICE = "web.code.git.service"
CODE_GIT_SEARCH = "web.code.git.search"
CODE_GIT_STATUS = "web.code.git.status"
CODE_GIT_REPOS = "web.code.git.repos"
CODE_COMPILE = "web.code.compile"

View File

@ -45,6 +45,9 @@ func _route_toast(m *ice.Message, space string, args ...string) {
toast(value[SPACE], count, total)
if msg := _route_push(m, value[SPACE], m.Cmd(SPACE, value[SPACE], args, ice.Maps{ice.MSG_DAEMON: ""})); msg.IsErr() || !cli.IsSuccess(msg) {
list = append(list, value[SPACE]+": "+msg.Result())
} else {
kit.If(msg.Result() == "", func() { msg.TableEcho() })
m.Push(SPACE, value[SPACE]).Push(ice.RES, msg.Result())
}
})
m.StatusTimeCount(ice.CMD, kit.Join(args, lex.SP), ice.SUCCESS, kit.Format("%d/%d", total-len(list), total))
@ -56,7 +59,7 @@ const ROUTE = "route"
func init() {
Index.MergeCommands(ice.Commands{
ROUTE: {Name: "route space:text cmds:text auto spide cmds build travel monitor prunes", Icon: "usr/icons/Podcasts.png", Help: "路由表", Actions: ice.MergeActions(ice.Actions{
ROUTE: {Name: "route space:text cmds:text auto spide cmds build travel prunes", Icon: "usr/icons/Podcasts.png", Help: "路由表", Actions: ice.MergeActions(ice.Actions{
ice.MAIN: {Help: "首页", Hand: func(m *ice.Message, arg ...string) {
ctx.ProcessField(m, CHAT_IFRAME, m.MergePod(""), arg...)
}},
@ -75,7 +78,7 @@ func init() {
"cmds": {Name: "cmds space index* args", Help: "命令", Hand: func(m *ice.Message, arg ...string) {
_route_toast(m, m.Option(SPACE), append([]string{m.Option(ctx.INDEX)}, kit.Split(m.Option(ctx.ARGS))...)...)
}},
"build": {Name: "build space", Help: "构建", Hand: func(m *ice.Message, arg ...string) {
cli.BUILD: {Name: "build space", Help: "构建", Hand: func(m *ice.Message, arg ...string) {
_route_toast(m, m.Option(SPACE), m.PrefixKey(), "_build")
m.Sleep("1s").Cmdy("", "travel")
}},
@ -111,14 +114,10 @@ func init() {
m.Push(key, "")
}
})
defer m.ProcessRefresh()
PushPodCmd(m, "", m.ActionKey())
ToastSuccess(m)
m.ProcessRefresh()
m.Table(func(value ice.Maps) { kit.If(value[SPACE], func() { mdb.HashCreate(m.Spawn(), kit.Simple(value)) }) })
}},
"monitor": {Help: "监控", Hand: func(m *ice.Message, arg ...string) {
m.ProcessOpen(m.Cmdv(SPIDE, "monitor", CLIENT_URL))
}},
}, ctx.CmdAction(), mdb.HashAction(mdb.SHORT, SPACE, mdb.FIELD, "time,space,type,module,version,md5,size,path,hostname", mdb.SORT, "type,space", mdb.ACTION, ice.MAIN)), Hand: func(m *ice.Message, arg ...string) {
if len(arg) > 1 {
_route_match(m, arg[0], func(value ice.Maps, i int, list []ice.Maps) {

View File

@ -11,7 +11,6 @@ import (
"shylinux.com/x/icebergs/base/aaa"
"shylinux.com/x/icebergs/base/cli"
"shylinux.com/x/icebergs/base/ctx"
"shylinux.com/x/icebergs/base/gdb"
"shylinux.com/x/icebergs/base/lex"
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/nfs"
@ -23,14 +22,11 @@ import (
func _serve_address(m *ice.Message) string { return Domain(tcp.LOCALHOST, m.Option(tcp.PORT)) }
func _serve_start(m *ice.Message) {
defer kit.For(kit.Split(m.Option(ice.DEV)), func(v string) {
m.Sleep("10ms").Cmd(SPACE, tcp.DIAL, ice.DEV, v, mdb.NAME, ice.Info.NodeName, TOKEN, m.Option(TOKEN))
m.Sleep30ms().Cmd(SPACE, tcp.DIAL, ice.DEV, v, mdb.NAME, ice.Info.NodeName, m.OptionSimple(TOKEN))
})
kit.If(m.Option(aaa.USERNAME), func() { aaa.UserRoot(m, m.Option(aaa.USERNICK), m.Option(aaa.USERNAME)) })
kit.If(m.Option(tcp.PORT) == tcp.RANDOM, func() { m.Option(tcp.PORT, m.Cmdx(tcp.PORT, aaa.RIGHT)) })
// kit.If(cli.IsWindows(), func() {
m.Go(func() { m.Cmd(SPIDE, ice.OPS, _serve_address(m)+"/exit", ice.Maps{CLIENT_TIMEOUT: "30ms"}) })
m.Sleep("30ms")
// })
kit.If(m.Option(aaa.USERNAME), func() { aaa.UserRoot(m, m.Option(aaa.USERNICK), m.Option(aaa.USERNAME)) })
m.Go(func() { m.Cmd(SPIDE, ice.OPS, _serve_address(m)+"/exit", ice.Maps{CLIENT_TIMEOUT: "30ms"}) }).Sleep30ms()
cli.NodeInfo(m, kit.Select(ice.Info.Hostname, m.Option(tcp.NODENAME)), SERVER)
m.Start("", m.OptionSimple(tcp.HOST, tcp.PORT)...)
}
@ -58,7 +54,7 @@ func _serve_main(m *ice.Message, w http.ResponseWriter, r *http.Request) bool {
r.Header.Set(ice.MSG_USERIP, strings.Split(r.RemoteAddr, nfs.DF)[0])
}
if m.Logs(r.Header.Get(ice.MSG_USERIP), r.Method, r.URL.String()); r.Method == http.MethodGet {
ispod := kit.Contains(r.Header.Get("Referer"), "/chat/pod/", "pod=") || kit.Contains(r.URL.String(), "/chat/pod/", "pod=")
ispod := kit.Contains(r.URL.String(), CHAT_POD, "pod=") || kit.Contains(r.Header.Get(Referer), CHAT_POD, "pod=")
if msg := m.Spawn(w, r).Options(ice.MSG_USERUA, r.UserAgent()); path.Join(r.URL.Path) == nfs.PS {
if !msg.IsCliUA() {
if r.URL.Path = kit.Select(nfs.PS, mdb.Config(m, ice.MAIN)); path.Join(r.URL.Path) != nfs.PS {
@ -68,11 +64,13 @@ func _serve_main(m *ice.Message, w http.ResponseWriter, r *http.Request) bool {
return !Render(RenderMain(msg), msg.Option(ice.MSG_OUTPUT), kit.List(msg.Optionv(ice.MSG_ARGS))...)
} else if p := path.Join(kit.Select(ice.USR_VOLCANOS, ice.USR_INTSHELL, msg.IsCliUA()), r.URL.Path); nfs.Exists(msg, p) {
return !Render(msg, ice.RENDER_DOWNLOAD, p)
} else if p = path.Join(nfs.USR, r.URL.Path); kit.HasPrefix(r.URL.Path, "/volcanos/", "/intshell/") && nfs.Exists(msg, p) {
} else if p = path.Join(nfs.USR, r.URL.Path); kit.HasPrefix(r.URL.Path, nfs.VOLCANOS, nfs.INTSHELL) && nfs.Exists(msg, p) {
return !Render(msg, ice.RENDER_DOWNLOAD, p)
} else if p = strings.TrimPrefix(r.URL.Path, "/require/"); kit.HasPrefix(r.URL.Path, "/require/src/", "/require/usr/icons/", "/require/usr/icebergs/") && nfs.Exists(msg, p) && !ispod {
} else if p = strings.TrimPrefix(r.URL.Path, nfs.REQUIRE); kit.HasPrefix(r.URL.Path, ice.REQUIRE_SRC, nfs.REQUIRE+ice.USR_ICONS, nfs.REQUIRE+ice.USR_ICEBERGS) && nfs.Exists(msg, p) {
if !ispod {
return !Render(msg, ice.RENDER_DOWNLOAD, p)
} else if p = path.Join("usr/node_modules/", strings.TrimPrefix(r.URL.Path, "/require/modules/")); kit.HasPrefix(r.URL.Path, "/require/modules/") && nfs.Exists(msg, p) {
}
} else if p = path.Join(ice.USR_MODULES, strings.TrimPrefix(r.URL.Path, ice.REQUIRE_MODULES)); kit.HasPrefix(r.URL.Path, ice.REQUIRE_MODULES) && nfs.Exists(msg, p) {
return !Render(msg, ice.RENDER_DOWNLOAD, p)
}
} else if path.Join(r.URL.Path) == nfs.PS {
@ -106,8 +104,8 @@ func _serve_handle(key string, cmd *ice.Command, m *ice.Message, w http.Response
r.ParseMultipartForm(kit.Int64(kit.Select("4096", r.Header.Get(ContentLength))))
kit.For(r.PostForm, func(k string, v []string) { _log(FORM, k, kit.Join(v, lex.SP)).Optionv(k, v) })
}
m.Option(ice.MSG_COUNT, "0")
kit.For(r.Cookies(), func(k, v string) { m.Optionv(k, v) })
m.Options(ice.MSG_COUNT, "0")
m.Options(ice.MSG_USERWEB, _serve_domain(m), ice.MSG_USERPOD, m.Option(ice.POD))
m.Options(ice.MSG_USERUA, r.Header.Get(UserAgent), ice.MSG_USERIP, r.Header.Get(ice.MSG_USERIP))
m.Options(ice.MSG_SESSID, kit.Select(m.Option(ice.MSG_SESSID), m.Option(CookieName(m.Option(ice.MSG_USERWEB)))))
@ -116,9 +114,14 @@ func _serve_handle(key string, cmd *ice.Command, m *ice.Message, w http.Response
})
defer func() { Render(m, m.Option(ice.MSG_OUTPUT), kit.List(m.Optionv(ice.MSG_ARGS))...) }()
if cmds, ok := _serve_auth(m, key, kit.Simple(m.Optionv(ice.MSG_CMDS)), w, r); ok {
defer func() { m.Cost(kit.Format("%s: %s %v", r.Method, m.PrefixPath()+path.Join(cmds...), m.FormatSize())) }()
defer func() {
m.Cost(kit.Format("%s: %s/%s %v", r.Method, m.PrefixKey(), path.Join(cmds...), m.FormatSize()))
}()
m.Option(ice.MSG_OPTS, kit.Simple(m.Optionv(ice.MSG_OPTION), func(k string) bool { return !strings.HasPrefix(k, ice.MSG_SESSID) }))
if m.Detailv(m.PrefixKey(), cmds); len(cmds) > 1 && cmds[0] == ctx.ACTION {
if !kit.IsIn(cmds[1], ctx.RUN, ctx.COMMAND) && m.Warn(r.Method == http.MethodGet, ice.ErrNotAllow) {
return
}
m.ActionHand(cmd, key, cmds[1], cmds[2:]...)
} else {
m.CmdHand(cmd, key, cmds...)
@ -143,9 +146,9 @@ func _serve_auth(m *ice.Message, key string, cmds []string, w http.ResponseWrite
return cmds, true
}
defer func() { m.Options(ice.MSG_CMDS, "", ice.MSG_SESSID, "") }()
if aaa.SessCheck(m, m.Option(ice.MSG_SESSID)); m.Option(ice.MSG_USERNAME) == "" && ice.Info.Localhost {
if aaa.SessCheck(m, m.Option(ice.MSG_SESSID)); m.Option(ice.MSG_USERNAME) == "" {
ls := kit.Simple(mdb.Cache(m, m.Option(ice.MSG_USERIP), func() ice.Any {
if tcp.IsLocalHost(m, m.Option(ice.MSG_USERIP)) {
if IsLocalHost(m) {
aaa.UserRoot(m)
return kit.Simple(m.Time(), m.OptionSplit(ice.MSG_USERNICK, ice.MSG_USERNAME, ice.MSG_USERROLE))
}
@ -161,8 +164,6 @@ func _serve_auth(m *ice.Message, key string, cmds []string, w http.ResponseWrite
}
const (
SERVE_START = "serve.start"
SSO = "sso"
URL = "url"
HTTP = "http"
@ -172,70 +173,52 @@ const (
FORM = "form"
BODY = "body"
ApplicationJSON = "application/json"
ApplicationOctet = "application/octet-stream"
SERVE_START = "serve.start"
)
const SERVE = "serve"
func init() {
Index.MergeCommands(ice.Commands{
P(ice.EXIT): {Hand: func(m *ice.Message, arg ...string) { m.Cmd(ice.EXIT) }},
PP(ice.VOLCANOS): {Hand: func(m *ice.Message, arg ...string) { m.RenderDownload(path.Join(ice.USR_VOLCANOS, path.Join(arg...))) }},
PP(ice.INTSHELL): {Hand: func(m *ice.Message, arg ...string) { m.RenderDownload(path.Join(ice.USR_INTSHELL, path.Join(arg...))) }},
SERVE: {Name: "serve name auto start main dark system publicip", Help: "服务器", Actions: ice.MergeActions(ice.Actions{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
cli.NodeInfo(m, ice.Info.Pathname, WORKER)
gdb.Watch(m, SERVE_START)
aaa.White(m, ice.INTSHELL)
aaa.White(m, ice.VOLCANOS)
aaa.White(m, nfs.REQUIRE)
aaa.White(m, LOGIN)
}},
DOMAIN: {Hand: func(m *ice.Message, arg ...string) {
kit.If(len(arg) > 0, func() { ice.Info.Domain, ice.Info.Localhost = arg[0], false })
m.Echo(ice.Info.Domain)
}},
cli.START: {Name: "start dev proto host port=9020 nodename username usernick", Hand: func(m *ice.Message, arg ...string) {
_serve_start(m)
}},
SERVE_START: {Hand: func(m *ice.Message, arg ...string) {
m.Go(func() {
m.Option(ice.MSG_USERIP, "127.0.0.1")
cli.Opens(m, mdb.Config(m, cli.OPEN))
ssh.PrintQRCode(m, tcp.PublishLocalhost(m, _serve_address(m)))
})
}},
cli.SYSTEM: {Help: "系统", Hand: func(m *ice.Message, arg ...string) { cli.Opens(m, "System Settings.app") }},
Index.MergeCommands(ice.Commands{P(ice.EXIT): {Hand: func(m *ice.Message, arg ...string) { m.Cmd(ice.EXIT) }},
SERVE: {Name: "serve name auto main host dark system", Help: "服务器", Actions: ice.MergeActions(ice.Actions{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { cli.NodeInfo(m, ice.Info.Pathname, WORKER) }},
ice.MAIN: {Name: "main index", Help: "首页", Hand: func(m *ice.Message, arg ...string) {
if m.Option(ctx.INDEX) == "" {
mdb.Config(m, ice.MAIN, "")
} else {
mdb.Config(m, ice.MAIN, CHAT_CMD+m.Option(ctx.INDEX)+"/")
mdb.Config(m, ice.MAIN, CHAT_CMD+m.Option(ctx.INDEX)+nfs.PS)
}
}},
"publicip": {Help: "公网", Hand: func(m *ice.Message, arg ...string) { m.Echo(kit.Formats(PublicIP(m))) }},
"dark": {Help: "主题", Hand: func(m *ice.Message, arg ...string) {
tcp.HOST: {Help: "公网", Hand: func(m *ice.Message, arg ...string) { m.Echo(kit.Formats(PublicIP(m))) }},
cli.DARK: {Help: "主题", Hand: func(m *ice.Message, arg ...string) {
if tcp.IsLocalHost(m, m.Option(ice.MSG_USERIP)) {
m.Cmd(cli.SYSTEM, "osascript", "-e", `tell app "System Events" to tell appearance preferences to set dark mode to not dark mode`)
}
}},
cli.SYSTEM: {Help: "系统", Hand: func(m *ice.Message, arg ...string) { cli.Opens(m, "System Settings.app") }},
cli.START: {Name: "start dev proto host port=9020 nodename username usernick", Hand: func(m *ice.Message, arg ...string) { _serve_start(m) }},
SERVE_START: {Hand: func(m *ice.Message, arg ...string) {
m.Go(func() {
m.Option(ice.MSG_USERIP, "127.0.0.1")
ssh.PrintQRCode(m, tcp.PublishLocalhost(m, _serve_address(m)))
cli.Opens(m, mdb.Config(m, cli.OPEN))
})
}},
}, mdb.HashAction(mdb.SHORT, mdb.NAME, mdb.FIELD, "time,status,name,proto,host,port"), mdb.ClearOnExitHashAction()), Hand: func(m *ice.Message, arg ...string) {
mdb.HashSelect(m, arg...)
m.StatusTimeCount(ice.MAIN, mdb.Config(m, ice.MAIN))
mdb.HashSelect(m, arg...).StatusTimeCount(ice.MAIN, mdb.Config(m, ice.MAIN))
}},
})
ice.AddMergeAction(func(c *ice.Context, key string, cmd *ice.Command, sub string, action *ice.Action) {
if strings.HasPrefix(sub, nfs.PS) {
kit.If(action.Hand == nil, func() { action.Hand = cmd.Hand })
sub = kit.Select(P(key, sub), PP(key, sub), strings.HasSuffix(sub, nfs.PS))
actions := ice.Actions{}
for k, v := range cmd.Actions {
kit.If(!kit.IsIn(k, ice.CTX_INIT, ice.CTX_EXIT), func() { actions[k] = v })
}
kit.If(action.Hand == nil, func() { action.Hand = cmd.Hand })
sub = kit.Select(P(key, sub), PP(key, sub), strings.HasSuffix(sub, nfs.PS))
c.Commands[sub] = &ice.Command{Name: kit.Select(cmd.Name, action.Name), Actions: ice.MergeActions(actions, ctx.CmdAction()), Hand: func(m *ice.Message, arg ...string) {
msg := m.Spawn(c, key, cmd)
defer m.Copy(msg)
action.Hand(msg, arg...)
m.Copy(msg)
}, RawHand: action.Hand}
}
})
@ -247,7 +230,6 @@ func Script(m *ice.Message, str string, arg ...ice.Any) string {
func ChatCmdPath(m *ice.Message, arg ...string) string {
if p := m.Option(ice.MSG_USERPOD); p != "" {
return path.Join(CHAT_POD, p, "/cmd/", kit.Select(m.PrefixKey(), path.Join(arg...)))
}
return path.Join(CHAT_CMD, kit.Select(m.PrefixKey(), path.Join(arg...)))
}
@ -255,7 +237,10 @@ func RequireFile(m *ice.Message, file string) string {
if strings.HasPrefix(file, nfs.PS) || strings.HasPrefix(file, ice.HTTP) {
return file
} else if file != "" {
return "/require/" + file
return nfs.REQUIRE + file
}
return ""
}
func IsLocalHost(m *ice.Message) bool {
return m.R.Header.Get("X-Forwarded-For") == "" && tcp.IsLocalHost(m, m.Option(ice.MSG_USERIP))
}

View File

@ -1,14 +1,12 @@
package web
import (
"net/http"
"path"
"strings"
"time"
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"
@ -25,29 +23,20 @@ func _share_link(m *ice.Message, p string, arg ...ice.Any) string {
return tcp.PublishLocalhost(m, MergeLink(m, kit.Select("", PP(SHARE, LOCAL), !strings.HasPrefix(p, nfs.PS) && !strings.HasPrefix(p, HTTP))+p, arg...))
}
func _share_cache(m *ice.Message, arg ...string) {
if pod := m.Option(ice.POD); ctx.PodCmd(m, CACHE, arg[0]) {
if m.Append(nfs.FILE) == "" {
m.RenderResult(m.Append(mdb.TEXT))
} else {
ShareLocalFile(m.Options(ice.POD, pod), m.Append(nfs.FILE))
}
} else {
if m.Cmdy(CACHE, arg[0]); m.Append(nfs.FILE) == "" {
m.RenderResult(m.Append(mdb.TEXT))
} else {
m.RenderDownload(m.Append(nfs.FILE), m.Append(mdb.TYPE), m.Append(mdb.NAME))
}
}
}
func _share_proxy(m *ice.Message) {
switch p := path.Join(ice.VAR_PROXY, m.Option(ice.POD), m.Option(nfs.PATH)); m.R.Method {
case http.MethodGet:
m.RenderDownload(p, m.Option(mdb.TYPE), m.Option(mdb.NAME))
case http.MethodPost:
if m.Warn(m.Option(SHARE) == "", ice.ErrNotValid) {
return
}
msg := m.Cmd(SHARE, m.Option(SHARE))
defer m.Cmd(SHARE, mdb.REMOVE, mdb.HASH, m.Option(SHARE))
if m.Warn(msg.Append(mdb.TEXT) == "") {
break
if m.Warn(msg.Append(mdb.TEXT) == "", ice.ErrNotValid) {
return
}
p := path.Join(ice.VAR_PROXY, msg.Append(mdb.TEXT), msg.Append(mdb.NAME))
if _, _, e := m.R.FormFile(UPLOAD); e == nil {
@ -55,7 +44,6 @@ func _share_proxy(m *ice.Message) {
}
m.RenderResult(m.Option(nfs.PATH))
}
}
const (
LOGIN = "login"
@ -75,9 +63,7 @@ func init() {
Index.MergeCommands(ice.Commands{
SHARE: {Name: "share hash auto login prunes", Help: "共享链", Actions: ice.MergeActions(ice.Actions{
mdb.CREATE: {Name: "create type name text", Hand: func(m *ice.Message, arg ...string) {
if m.Option(mdb.TYPE) == LOGIN {
arg = append(arg, mdb.TEXT, tcp.PublishLocalhost(m, m.Option(mdb.TEXT)))
}
kit.If(m.Option(mdb.TYPE) == LOGIN, func() { arg = append(arg, mdb.TEXT, tcp.PublishLocalhost(m, m.Option(mdb.TEXT))) })
mdb.HashCreate(m, arg, aaa.USERNICK, m.Option(ice.MSG_USERNICK), aaa.USERNAME, m.Option(ice.MSG_USERNAME), aaa.USERROLE, m.Option(ice.MSG_USERROLE))
m.Option(mdb.LINK, _share_link(m, P(SHARE, m.Result())))
}},
@ -113,11 +99,8 @@ func init() {
}
}},
}, aaa.WhiteAction(ctx.COMMAND, ctx.RUN), mdb.HashAction(mdb.FIELD, "time,hash,type,name,text,usernick,username,userrole", mdb.EXPIRE, mdb.DAYS)), Hand: func(m *ice.Message, arg ...string) {
if mdb.HashSelect(m, arg...); len(arg) > 0 {
link := _share_link(m, P(SHARE, arg[0]))
m.PushQRCode(cli.QRCODE, link)
m.PushScript(nfs.SCRIPT, link)
m.PushAnchor(link)
if kit.IsIn(m.Option(ice.MSG_USERROLE), aaa.ROOT, aaa.TECH) || len(arg) > 0 && arg[0] != "" {
mdb.HashSelect(m, arg...)
}
}},
PP(SHARE, CACHE): {Hand: func(m *ice.Message, arg ...string) { _share_cache(m, arg...) }},
@ -173,6 +156,6 @@ func ShareLocalFile(m *ice.Message, arg ...string) {
share := m.Cmdx(SHARE, mdb.CREATE, mdb.TYPE, PROXY, mdb.NAME, p, mdb.TEXT, m.Option(ice.POD))
defer m.Cmd(SHARE, mdb.REMOVE, mdb.HASH, share)
url := tcp.PublishLocalhost(m, MergeLink(m, PP(SHARE, PROXY), SHARE, share))
m.Cmd(SPACE, m.Option(ice.POD), SPIDE, PROXY, "url", url, nfs.SIZE, size, CACHE, cache.Format(ice.MOD_TIME), UPLOAD, mdb.AT+p)
m.Cmd(SPACE, m.Option(ice.POD), SPIDE, PROXY, URL, url, nfs.SIZE, size, CACHE, cache.Format(ice.MOD_TIME), UPLOAD, mdb.AT+p)
m.RenderDownload(kit.Select(p, pp, file.ExistsFile(pp)))
}

View File

@ -49,11 +49,10 @@ func _space_dial(m *ice.Message, dev, name string, arg ...string) {
}
func _space_fork(m *ice.Message) {
addr := kit.Select(m.R.RemoteAddr, m.R.Header.Get(ice.MSG_USERADDR))
text := strings.ReplaceAll(kit.Select(addr, m.Option(mdb.TEXT)), "%2F", nfs.PS)
name := kit.ReplaceAll(kit.Select(addr, m.Option(mdb.NAME)), "[", "_", "]", "_", nfs.DF, "_", nfs.PT, "_")
text := kit.Select(addr, m.Option(mdb.TEXT))
text = strings.ReplaceAll(text, "%2F", "/")
if kit.IsIn(m.Option(mdb.TYPE), PORTAL) && m.Option(mdb.NAME) != html.CHROME || !(ice.Info.Localhost && tcp.IsLocalHost(m, m.R.RemoteAddr) ||
m.Option(TOKEN) != "" && m.Cmdv(TOKEN, m.Option(TOKEN), mdb.TIME) > m.Time()) || mdb.HashSelect(m.Spawn(), name).Length() > 0 {
if kit.IsIn(m.Option(mdb.TYPE), PORTAL) && m.Option(mdb.NAME) != html.CHROME || mdb.HashSelect(m.Spawn(), name).Length() > 0 ||
!(IsLocalHost(m) || m.Option(TOKEN) != "" && m.Cmdv(TOKEN, m.Option(TOKEN), mdb.TIME) > m.Time()) {
name, text = kit.Hashs(name), kit.Select(addr, m.Option(mdb.NAME), m.Option(mdb.TEXT))
}
if m.Option(mdb.TYPE) == WORKER {
@ -61,12 +60,11 @@ func _space_fork(m *ice.Message) {
text = p
}
}
args := kit.Simple(mdb.TYPE, kit.Select(WORKER, m.Option(mdb.TYPE)), mdb.NAME, name, mdb.TEXT, text, m.OptionSimple(cli.DAEMON, ice.MSG_USERUA), m.OptionSimple(nfs.MODULE, nfs.VERSION))
args := kit.Simple(mdb.TYPE, kit.Select(WORKER, m.Option(mdb.TYPE)), mdb.NAME, name, mdb.TEXT, text, m.OptionSimple(nfs.MODULE, nfs.VERSION, cli.DAEMON, ice.MSG_USERUA))
if c, e := websocket.Upgrade(m.W, m.R); !m.Warn(e) {
gdb.Go(m, func() {
defer mdb.HashCreateDeferRemove(m, args, kit.Dict(mdb.TARGET, c))()
switch m.Option(mdb.TYPE) {
case SERVER:
case WORKER:
defer gdb.EventDeferEvent(m, DREAM_OPEN, args)(DREAM_CLOSE, args)
case PORTAL:
@ -130,7 +128,7 @@ func _space_exec(m *ice.Message, source, target []string, c *websocket.Conn) {
m.Push(mdb.LINK, m.MergePod(kit.Select("", source, -1)))
default:
m.Options("__target", kit.Reverse(kit.Simple(source))).OptionDefault(ice.MSG_COUNT, "0")
kit.If(aaa.Right(m, m.Detailv()), func() { m.TryCatch(m, true, func(_ *ice.Message) { m = m.Cmd() }) })
kit.If(aaa.Right(m, m.Detailv()), func() { m.TryCatch(true, func(_ *ice.Message) { m = m.Cmd() }) })
}
defer m.Cost(kit.Format("%v->%v %v %v", source, target, m.Detailv(), m.FormatSize()))
_space_echo(m.Set(ice.MSG_OPTS).Options(log.DEBUG, m.Option(log.DEBUG)), []string{}, kit.Reverse(kit.Simple(source)), c)
@ -142,21 +140,21 @@ func _space_echo(m *ice.Message, source, target []string, c *websocket.Conn) {
}
}
func _space_send(m *ice.Message, name string, arg ...string) (h string) {
wait, done := m.Wait(func(msg *ice.Message, arg ...string) {
wait, done := m.Wait("180s", func(msg *ice.Message, arg ...string) {
m.Cost(kit.Format("%v->[%v] %v %v", m.Optionv(ice.MSG_SOURCE), name, m.Detailv(), msg.FormatSize())).Copy(msg)
})
h = mdb.HashCreate(m.Spawn(), mdb.TYPE, tcp.SEND, mdb.NAME, kit.Keys(name, m.Target().ID()), mdb.TEXT, kit.Join(arg, lex.SP), kit.Dict(mdb.TARGET, done))
defer mdb.HashRemove(m.Spawn(), mdb.HASH, h)
if target := kit.Split(name, nfs.PT, nfs.PT); mdb.HashSelectDetail(m, target[0], func(value ice.Map) {
if target := kit.Split(name, nfs.PT, nfs.PT); !mdb.HashSelectDetail(m, target[0], func(value ice.Map) {
if c, ok := value[mdb.TARGET].(*websocket.Conn); !m.Warn(!ok, ice.ErrNotValid, mdb.TARGET) {
kit.For([]string{ice.MSG_USERROLE}, func(k string) { m.Optionv(k, m.Optionv(k)) })
kit.For(m.Optionv(ice.MSG_OPTS), func(k string) { m.Optionv(k, m.Optionv(k)) })
_space_echo(m.Set(ice.MSG_DETAIL, arg...), []string{h}, target, c)
}
}) {
wait()
} else {
m.Warn(kit.IndexOf([]string{ice.OPS, ice.DEV}, target[0]) == -1, ice.ErrNotFound, SPACE, name)
} else {
m.Warn(!wait(), "time out")
}
return
}
@ -182,7 +180,7 @@ func init() {
kit.If(kit.IsIn(value[mdb.TYPE], WORKER, SERVER), func() { m.Push(arg[0], value[mdb.NAME]) })
})
case mdb.ICON:
m.Cmdy(nfs.DIR, "usr/icons/", nfs.PATH)
m.Cmdy(nfs.DIR, ice.USR_ICONS, nfs.PATH)
case ctx.INDEX:
if space := m.Option(SPACE); space != "" {
m.Options(SPACE, []string{}).Cmdy(SPACE, space, mdb.INPUTS, arg)
@ -200,7 +198,7 @@ func init() {
Index.MergeCommands(ice.Commands{
SPACE: {Name: "space name cmds auto", Help: "空间站", Actions: ice.MergeActions(ice.Actions{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { aaa.White(m, SPACE, ice.MAIN) }},
ice.MAIN: {Name: "main index", Hand: func(m *ice.Message, arg ...string) {
ice.MAIN: {Name: "main index", Help: "首页", Hand: func(m *ice.Message, arg ...string) {
if len(arg) > 0 {
mdb.Config(m, ice.MAIN, m.Option(ctx.INDEX))
return
@ -212,22 +210,15 @@ func init() {
if mdb.IsSearchPreview(m, arg) {
m.Cmds("", func(value ice.Maps) {
switch value[mdb.TYPE] {
case MASTER:
m.PushSearch(mdb.TEXT, m.Cmdv(SPIDE, value[mdb.NAME], CLIENT_ORIGIN), value)
case SERVER:
m.PushSearch(mdb.TEXT, m.MergePod(value[mdb.NAME]), value)
case MASTER:
m.PushSearch(mdb.TEXT, m.Cmdv(SPIDE, value[mdb.NAME], CLIENT_ORIGIN), value)
}
})
}
}},
mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) {
switch arg[0] {
case SPACE:
m.Cmdy("").CutTo(mdb.NAME, arg[0])
default:
mdb.HashInputs(m, arg)
}
}},
cli.START: {Hand: func(m *ice.Message, arg ...string) { m.Cmdy("", tcp.DIAL, arg) }},
tcp.DIAL: {Name: "dial dev=ops name", Hand: func(m *ice.Message, arg ...string) {
if strings.HasPrefix(m.Option(ice.DEV), HTTP) {
m.Cmd(SPIDE, mdb.CREATE, m.OptionSimple(ice.DEV))
@ -235,7 +226,6 @@ func init() {
}
_space_dial(m, m.Option(ice.DEV), kit.Select(ice.Info.NodeName, m.Option(mdb.NAME)), arg...)
}},
cli.START: {Hand: func(m *ice.Message, arg ...string) { m.Cmdy("", tcp.DIAL, arg) }},
mdb.REMOVE: {Hand: func(m *ice.Message, arg ...string) {
defer mdb.HashModifyDeferRemove(m, m.OptionSimple(mdb.NAME), mdb.STATUS, cli.STOP)()
m.Cmd("", m.Option(mdb.NAME), ice.EXIT)
@ -249,9 +239,9 @@ func init() {
OPEN: {Hand: func(m *ice.Message, arg ...string) {
switch m.Option(mdb.TYPE) {
case MASTER:
ctx.ProcessOpen(m, m.Cmdv(SPIDE, m.Option(mdb.NAME), CLIENT_ORIGIN))
m.ProcessOpen(m.Cmdv(SPIDE, m.Option(mdb.NAME), CLIENT_ORIGIN))
default:
ctx.ProcessOpen(m, m.MergePod(m.Option(mdb.NAME), arg))
m.ProcessOpen(m.MergePod(m.Option(mdb.NAME), arg))
}
}},
nfs.PS: {Hand: func(m *ice.Message, arg ...string) { _space_fork(m) }},

View File

@ -27,7 +27,7 @@ func _spide_create(m *ice.Message, name, link string) {
dir, file := path.Split(u.EscapedPath())
m.Logs(mdb.INSERT, SPIDE, name, LINK, link)
mdb.HashSelectUpdate(m, mdb.HashCreate(m, CLIENT_NAME, name), func(value ice.Map) {
value[SPIDE_CLIENT] = kit.Dict(mdb.NAME, name, SPIDE_METHOD, http.MethodGet, "url", link, ORIGIN, u.Scheme+"://"+u.Host,
value[SPIDE_CLIENT] = kit.Dict(mdb.NAME, name, SPIDE_METHOD, http.MethodGet, URL, link, ORIGIN, u.Scheme+"://"+u.Host,
tcp.PROTOCOL, u.Scheme, tcp.HOSTNAME, u.Hostname(), tcp.HOST, u.Host, nfs.PATH, dir, nfs.FILE, file, cli.TIMEOUT, "300s",
)
})
@ -35,7 +35,7 @@ func _spide_create(m *ice.Message, name, link string) {
}
func _spide_show(m *ice.Message, name string, arg ...string) {
file := ""
action, arg := _spide_args(m, arg, SPIDE_RAW, SPIDE_MSG, SPIDE_CACHE, SPIDE_SAVE)
action, arg := _spide_args(m, arg, SPIDE_RAW, SPIDE_MSG, SPIDE_SAVE, SPIDE_CACHE)
kit.If(action == SPIDE_SAVE, func() { file, arg = arg[0], arg[1:] })
msg := mdb.HashSelects(m.Spawn(), name)
method, arg := _spide_args(m, arg, http.MethodGet, http.MethodPut, http.MethodPost, http.MethodDelete)
@ -61,17 +61,13 @@ func _spide_show(m *ice.Message, name string, arg ...string) {
return
}
defer res.Body.Close()
m.Push(mdb.TYPE, STATUS)
m.Push(mdb.NAME, res.StatusCode)
m.Push(mdb.VALUE, res.Status)
m.Cost(cli.STATUS, res.Status, nfs.SIZE, kit.FmtSize(kit.Int64(res.Header.Get(ContentLength))), mdb.TYPE, res.Header.Get(ContentType))
m.Push(mdb.TYPE, STATUS).Push(mdb.NAME, res.StatusCode).Push(mdb.VALUE, res.Status)
kit.For(res.Header, func(k string, v []string) {
if m.Option(log.DEBUG) == ice.TRUE {
m.Logs(RESPONSE, k, v)
}
m.Push(mdb.TYPE, SPIDE_HEADER)
m.Push(mdb.NAME, k)
m.Push(mdb.VALUE, v[0])
m.Push(mdb.TYPE, SPIDE_HEADER).Push(mdb.NAME, k).Push(mdb.VALUE, v[0])
})
mdb.HashSelectUpdate(m, name, func(value ice.Map) {
kit.For(res.Cookies(), func(v *http.Cookie) {
@ -79,9 +75,7 @@ func _spide_show(m *ice.Message, name string, arg ...string) {
if m.Option(log.DEBUG) == ice.TRUE {
m.Logs(RESPONSE, v.Name, v.Value)
}
m.Push(mdb.TYPE, COOKIE)
m.Push(mdb.NAME, v.Name)
m.Push(mdb.VALUE, v.Value)
m.Push(mdb.TYPE, COOKIE).Push(mdb.NAME, v.Name).Push(mdb.VALUE, v.Value)
})
})
if m.Warn(res.StatusCode != http.StatusOK && res.StatusCode != http.StatusCreated, ice.ErrNotValid, uri, cli.STATUS, res.Status) {
@ -108,8 +102,7 @@ func _spide_body(m *ice.Message, method string, arg ...string) (io.Reader, ice.M
case SPIDE_FORM:
arg = kit.Simple(arg, func(v string) string { return url.QueryEscape(v) })
_data := kit.JoinKV("=", "&", arg[1:]...)
m.Debug("post %v %v", len(_data), _data)
head[ContentType], body = ContentFORM, bytes.NewBufferString(_data)
head[ContentType], body = ApplicationForm, bytes.NewBufferString(_data)
case SPIDE_PART:
head[ContentType], body = _spide_part(m, arg...)
case SPIDE_FILE:
@ -126,7 +119,6 @@ func _spide_body(m *ice.Message, method string, arg ...string) (io.Reader, ice.M
data := ice.Map{}
kit.For(arg, func(k, v string) { kit.Value(data, k, v) })
_data := kit.Format(data)
m.Debug("post %v %v", len(_data), _data)
head[ContentType], body = ApplicationJSON, bytes.NewBufferString(_data)
}
return body, head, arg[:0]
@ -186,7 +178,7 @@ func _spide_save(m *ice.Message, action, file, uri string, res *http.Response) {
if action == SPIDE_RAW {
m.SetResult()
} else {
m.SetAppend().SetResult()
m.SetResult().SetAppend()
}
switch action {
case SPIDE_RAW:
@ -220,8 +212,8 @@ func _spide_save(m *ice.Message, action, file, uri string, res *http.Response) {
const (
SPIDE_RAW = "raw"
SPIDE_MSG = "msg"
SPIDE_CACHE = "cache"
SPIDE_SAVE = "save"
SPIDE_CACHE = "cache"
SPIDE_BODY = "body"
SPIDE_FORM = "form"
@ -241,10 +233,13 @@ const (
Referer = "Referer"
Accept = "Accept"
ContentFORM = "application/x-www-form-urlencoded"
ContentPNG = "image/png"
ContentHTML = "text/html"
ContentCSS = "text/css"
ApplicationForm = "application/x-www-form-urlencoded"
ApplicationOctet = "application/octet-stream"
ApplicationJSON = "application/json"
IMAGE_PNG = "image/png"
TEXT_HTML = "text/html"
TEXT_CSS = "text/css"
)
const (
SPIDE_CLIENT = "client"
@ -294,36 +289,34 @@ func init() {
case COOKIE:
switch arg[0] {
case mdb.KEY:
m.Push(arg[0], "sessid")
m.Push(arg[0], ice.MSG_SESSID)
}
case HEADER:
switch arg[0] {
case mdb.KEY:
m.Push(arg[0], "Authorization")
m.Push(arg[0], Authorization)
}
default:
mdb.HashSelectValue(m.Spawn(), func(value ice.Map) { m.Push(kit.Select(ORIGIN, arg, 0), kit.Value(value, CLIENT_ORIGIN)) })
}
}},
mdb.CREATE: {Name: "create name link", Hand: func(m *ice.Message, arg ...string) { _spide_create(m, m.Option(mdb.NAME), m.Option(LINK)) }},
HEADER: {Name: "header key* value", Hand: func(m *ice.Message, arg ...string) {
mdb.HashModify(m, m.OptionSimple(CLIENT_NAME), kit.Keys(HEADER, m.Option(mdb.KEY)), m.Option(mdb.VALUE))
}},
COOKIE: {Name: "cookie key* value", Hand: func(m *ice.Message, arg ...string) {
mdb.HashModify(m, m.OptionSimple(CLIENT_NAME), kit.Keys(COOKIE, m.Option(mdb.KEY)), m.Option(mdb.VALUE))
}},
HEADER: {Name: "header key* value", Hand: func(m *ice.Message, arg ...string) {
mdb.HashModify(m, m.OptionSimple(CLIENT_NAME), kit.Keys(HEADER, m.Option(mdb.KEY)), m.Option(mdb.VALUE))
}},
MERGE: {Hand: func(m *ice.Message, arg ...string) {
m.Echo(kit.MergeURL2(m.Cmdv("", arg[0], CLIENT_URL), arg[1], arg[2:]))
}},
PROXY: {Name: "proxy url size cache upload", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(SPIDE, ice.DEV, SPIDE_RAW, http.MethodPost, m.Option("url"), SPIDE_PART, arg[2:])
m.Cmdy(SPIDE, ice.DEV, SPIDE_RAW, http.MethodPost, m.Option(URL), SPIDE_PART, arg[2:])
}},
}, mdb.HashAction(mdb.SHORT, CLIENT_NAME, mdb.FIELD, "time,client.name,client.url")), Hand: func(m *ice.Message, arg ...string) {
if len(arg) < 2 || arg[0] == "" || (len(arg) > 3 && arg[3] == "") {
mdb.HashSelect(m, kit.Slice(arg, 0, 1)...).Sort(CLIENT_NAME)
if len(arg) > 0 && arg[0] != "" {
m.Action(COOKIE, HEADER)
}
kit.If(len(arg) > 0 && arg[0] != "", func() { m.Action(COOKIE, HEADER) })
} else {
_spide_show(m, arg[0], arg[1:]...)
}

View File

@ -1,11 +1,10 @@
package web
import (
"encoding/base64"
"net/http"
"strings"
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/aaa"
"shylinux.com/x/icebergs/base/lex"
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/nfs"
@ -29,6 +28,9 @@ func init() {
m.Echo("请授权 %s 代码权限\n", m.Option(tcp.HOST)).EchoButton(CONFIRM)
}},
CONFIRM: {Hand: func(m *ice.Message, arg ...string) {
if m.Warn(m.R.Method != http.MethodPost, ice.ErrNotAllow) {
return
}
msg := m.Cmd("", mdb.CREATE, mdb.TYPE, Basic, mdb.NAME, m.Option(ice.MSG_USERNAME), mdb.TEXT, m.Option(tcp.HOST))
m.ProcessReplace(kit.MergeURL2(m.Option(tcp.HOST), ChatCmdPath(m, m.PrefixKey(), SET),
TOKEN, strings.Replace(UserHost(m), "://", kit.Format("://%s:%s@", m.Option(ice.MSG_USERNAME), msg.Result()), 1)))
@ -41,47 +43,6 @@ func init() {
}).Cmd(nfs.SAVE, kit.HomePath(FILE), strings.Join(list, lex.NL)+lex.NL)
m.ProcessClose()
}},
}, mdb.HashAction(mdb.EXPIRE, mdb.MONTH, mdb.SHORT, mdb.UNIQ, mdb.FIELD, "time,hash,type,name,text")), Hand: func(m *ice.Message, arg ...string) {
if mdb.HashSelect(m, arg...); len(arg) > 0 {
return
u := kit.ParseURL(m.Option(ice.MSG_USERWEB))
p := tcp.PublishLocalhost(m, kit.Format("%s://%s:%s@%s", u.Scheme, m.Append(aaa.USERNAME), m.Append(TOKEN), u.Host))
m.EchoScript(p).EchoScript(kit.Format("echo '%s' >>~/.git-credentials", p))
}
}},
})
Index.MergeCommands(ice.Commands{
"/check": {Hand: func(m *ice.Message, arg ...string) {
kit.For(m.R.Header, func(key string, value []string) { m.Debug("what %v %v", key, value) })
if BasicSess(m); m.Option(ice.MSG_USERNAME) == "" {
BasicCheck(m, "请输入账号密码")
}
}},
"/login": {Hand: func(m *ice.Message, arg ...string) { RenderMain(m) }},
"/auths": {Hand: func(m *ice.Message, arg ...string) {
kit.If(m.R.URL.Query().Get(ice.MSG_SESSID), func(p string) { RenderCookie(m, m.Option(ice.MSG_SESSID, p)) })
RenderRedirect(m, m.R.URL.Query().Get("redirect_uri"))
}},
}, mdb.HashAction(mdb.SHORT, mdb.UNIQ, mdb.FIELD, "time,hash,type,name,text", mdb.EXPIRE, mdb.MONTH))},
})
}
func BasicSess(m *ice.Message) {
m.Options(ice.MSG_USERWEB, _serve_domain(m))
m.Options(ice.MSG_SESSID, kit.Select(m.Option(ice.MSG_SESSID), m.Option(CookieName(m.Option(ice.MSG_USERWEB)))))
aaa.SessCheck(m, m.Option(ice.MSG_SESSID))
}
func BasicCheck(m *ice.Message, realm string) bool {
switch ls := kit.Split(m.R.Header.Get(Authorization)); kit.Select("", ls, 0) {
case Basic:
if buf, err := base64.StdEncoding.DecodeString(kit.Select("", ls, 1)); !m.Warn(err) {
if ls := strings.SplitN(string(buf), ":", 2); !m.Warn(len(ls) < 2) {
if msg := m.Cmd(TOKEN, ls[1]); !m.Warn(msg.Time() > msg.Append(mdb.TIME)) {
return true
}
}
}
}
m.W.Header().Add("WWW-Authenticate", kit.Format(`Basic realm="%s"`, realm))
m.RenderStatusUnauthorized()
return false
}

View File

@ -37,7 +37,7 @@ func (f *Frame) Start(m *ice.Message, arg ...string) {
msg := m.Spawn(c)
if pf, ok := p.Server().(*Frame); ok && pf.ServeMux != nil {
route := nfs.PS + c.Name + nfs.PS
msg.Log("route", "%s <= %s", p.Name, route)
msg.Log(ROUTE, "%s <= %s", p.Name, route)
pf.Handle(route, http.StripPrefix(path.Dir(route), f))
list[c] = path.Join(list[p], route)
}
@ -46,9 +46,9 @@ func (f *Frame) Start(m *ice.Message, arg ...string) {
continue
}
func(key string, cmd *ice.Command) {
msg.Log("route", "%s <- %s", c.Name, key)
msg.Log(ROUTE, "%s <- %s", c.Name, key)
f.HandleFunc(key, func(w http.ResponseWriter, r *http.Request) {
m.TryCatch(m.Spawn(key, cmd, c, w, r), true, func(msg *ice.Message) { _serve_handle(key, cmd, msg, w, r) })
m.Spawn(key, cmd, c, w, r).TryCatch(true, func(msg *ice.Message) { _serve_handle(key, cmd, msg, w, r) })
})
ice.Info.Route[path.Join(list[c], key)+kit.Select("", nfs.PS, strings.HasSuffix(key, nfs.PS))] = ctx.FileURI(cmd.FileLine())
}(key, cmd)
@ -63,11 +63,7 @@ func (f *Frame) Start(m *ice.Message, arg ...string) {
gdb.Event(m, SERVE_START, arg)
m.Warn(f.Server.Serve(l))
})
if m.IsErr() {
fmt.Println()
fmt.Println(m.Result())
m.Cmd(ice.QUIT)
}
kit.If(m.IsErr(), func() { fmt.Println(); fmt.Println(m.Result()); m.Cmd(ice.QUIT) })
}
}
func (f *Frame) Close(m *ice.Message, arg ...string) {}

46
conf.go
View File

@ -20,14 +20,14 @@ const (
SUCCESS = "success"
FAILURE = "failure"
PROCESS = "process"
WINDOWS = "windows"
HTTPS = "https"
HTTP = "http"
MAIN = "main"
AUTO = "auto"
VIEW = "view"
LIST = "list"
BACK = "back"
MAIN = "main"
BASE = "base"
CORE = "core"
@ -37,15 +37,14 @@ const (
HUB = "hub"
COM = "com"
DEV = "dev"
APP = "app"
OPS = "ops"
APP = "app"
ICE = "ice"
CAN = "can"
POD = "pod"
CMD = "cmd"
ARG = "arg"
ENV = "env"
RUN = "run"
RES = "res"
@ -53,16 +52,20 @@ const (
)
const ( // REPOS
CONTEXTS = "contexts"
LEARNING = "learning"
RELEASE = "release"
ICONS = "icons"
VOLCANOS = "volcanos"
INTSHELL = "intshell"
ICEBERGS = "icebergs"
TOOLKITS = "toolkits"
VOLCANOS = "volcanos"
LEARNING = "learning"
MATRIX = "matrix"
INSTALL = "install"
REQUIRE = "require"
PUBLISH = "publish"
RELEASE = "release"
PORTAL = "portal"
LOCAL = "local"
)
const ( // MOD
MOD_DIR = 0750
@ -96,34 +99,35 @@ const ( // DIR
STORY = "story"
INDEX_CSS = "index.css"
CONST_JS = "const.js"
PROTO_JS = "proto.js"
FRAME_JS = "frame.js"
INDEX_SH = "index.sh"
FAVICON_ICO = "/favicon.ico"
PLUGIN_INPUT = "/volcanos/plugin/input/"
PLUGIN_LOCAL = "/volcanos/plugin/local/"
PLUGIN_STORY = "/volcanos/plugin/story/"
PLUGIN_TABLE_JS = "/volcanos/plugin/table.js"
PLUGIN_INPUT = "/plugin/input/"
PLUGIN_LOCAL = "/plugin/local/"
PLUGIN_STORY = "/plugin/story/"
PLUGIN_TABLE_JS = "/plugin/table.js"
REQUIRE_MODULES = "/require/modules/"
REQUIRE_USR = "/require/usr/"
REQUIRE_SRC = "/require/src/"
ISH_PLUGED = ".ish/pluged/"
USR_MODULES = "usr/node_modules/"
USR_INSTALL = "usr/install/"
USR_REQUIRE = "usr/require/"
USR_PUBLISH = "usr/publish/"
USR_RELEASE = "usr/release/"
USR_LEARNING = "usr/learning/"
USR_VOLCANOS = "usr/volcanos/"
USR_INTSHELL = "usr/intshell/"
USR_ICEBERGS = "usr/icebergs/"
USR_TOOLKITS = "usr/toolkits/"
USR_VOLCANOS = "usr/volcanos/"
USR_LEARNING = "usr/learning/"
USR_INSTALL = "usr/install/"
USR_REQUIRE = "usr/require/"
USR_PUBLISH = "usr/publish/"
USR_PORTAL = "usr/portal/"
USR_LOCAL = "usr/local/"
USR_ICONS = "usr/icons/"
USR_LOCAL = "usr/local/"
USR_LOCAL_GO = "usr/local/go/"
USR_LOCAL_GO_BIN = "usr/local/go/bin/"
USR_LOCAL_BIN = "usr/local/bin/"
@ -265,8 +269,6 @@ const ( // PROCESS
FIELDS_DETAIL = "detail"
)
const ( // CTX
CTX_ARG = "ctx_arg"
CTX_DAEMON = "ctx_daemon"
CTX_FOLLOW = "follow"
CTX_BEGIN = "begin"
@ -291,9 +293,9 @@ const ( // Err
ErrNotLogin = "not login: "
ErrNotRight = "not right: "
ErrNotAllow = "not allow: "
ErrNotValid = "not valid: "
ErrNotFound = "not found: "
ErrNotAllow = "not allow: "
ErrNotStart = "not start: "
ErrNotImplement = "not implement: "
@ -316,8 +318,8 @@ const ( // mdb
VALUE = "value"
EXTRA = "extra"
META = "meta"
HASH = "hash"
TIME = "time"
HASH = "hash"
TYPE = "type"
NAME = "name"
TEXT = "text"
@ -327,8 +329,8 @@ const ( // web
SERVE = "serve"
SPACE = "space"
TITLE = "title"
THEME = "theme"
TITLE = "title"
)
const ( // gdb
EVENT = "event"

View File

@ -74,9 +74,9 @@ func init() {
m.Cmd("", mdb.CREATE, m.OptionSimple(mdb.TYPE, mdb.NAME, mdb.TEXT))
}},
web.DOWNLOAD: {Hand: func(m *ice.Message, arg ...string) {
ctx.ProcessOpen(m, web.MergeURL2(m, web.SHARE_LOCAL+m.Option(mdb.TEXT), "filename", m.Option(mdb.NAME)))
m.ProcessOpen(web.MergeURL2(m, web.SHARE_LOCAL+m.Option(mdb.TEXT), "filename", m.Option(mdb.NAME)))
}},
web.DISPLAY: {Help: "预览", Hand: func(m *ice.Message, arg ...string) {
ctx.DISPLAY: {Help: "预览", Hand: func(m *ice.Message, arg ...string) {
if link := web.SHARE_LOCAL + m.Option(mdb.TEXT); _favor_is_image(m, m.Option(mdb.NAME), m.Option(mdb.TYPE)) {
m.EchoImages(link)
} else if _favor_is_video(m, m.Option(mdb.NAME), m.Option(mdb.TYPE)) {
@ -120,9 +120,9 @@ func init() {
if strings.HasPrefix(m.Append(mdb.TEXT), ice.VAR_FILE) {
text = web.SHARE_LOCAL + m.Append(mdb.TEXT)
if m.PushDownload(mdb.LINK, m.Append(mdb.NAME), text); len(arg) > 0 && _favor_is_image(m, m.Append(mdb.NAME), m.Append(mdb.TYPE)) {
m.PushImages(web.DISPLAY, text)
m.PushImages(ctx.DISPLAY, text)
} else if _favor_is_video(m, m.Append(mdb.NAME), m.Append(mdb.TYPE)) {
m.PushVideos(web.DISPLAY, text)
m.PushVideos(ctx.DISPLAY, text)
}
text = tcp.PublishLocalhost(m, web.MergeLink(m, text))
}
@ -146,7 +146,7 @@ func init() {
default:
if strings.HasPrefix(value[mdb.TEXT], ice.VAR_FILE) {
if _favor_is_image(m, value[mdb.NAME], value[mdb.TYPE]) || _favor_is_video(m, value[mdb.NAME], value[mdb.TYPE]) || _favor_is_audio(m, value[mdb.NAME], value[mdb.TYPE]) {
m.PushButton(web.DISPLAY, web.DOWNLOAD, mdb.REMOVE)
m.PushButton(ctx.DISPLAY, web.DOWNLOAD, mdb.REMOVE)
} else {
m.PushButton(web.DOWNLOAD, mdb.REMOVE)
}

View File

@ -97,6 +97,7 @@ func init() {
"/": {Hand: func(m *ice.Message, arg ...string) {
m.Option("language.list", m.Cmd(nfs.DIR, path.Join(ice.SRC_TEMPLATE, m.PrefixKey(), aaa.LANGUAGE), nfs.FILE).Appendv(nfs.FILE))
m.Option("theme.list", m.Cmd(nfs.DIR, path.Join(ice.SRC_TEMPLATE, m.PrefixKey(), aaa.THEME), nfs.FILE).Appendv(nfs.FILE))
m.Option(ICONS, mdb.Conf(m, "web.chat.icons", kit.Keym(nfs.PATH)))
m.Option(nfs.REPOS, m.Cmdv(web.SPIDE, ice.HUB, web.CLIENT_URL))
if gdb.Event(m, HEADER_AGENT); !_header_check(m, arg...) {
return

View File

@ -4,20 +4,22 @@ import (
"strings"
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/ctx"
"shylinux.com/x/icebergs/base/lex"
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/nfs"
kit "shylinux.com/x/toolkits"
)
func init() {
const ICONS = "icons"
func init() {
Index.MergeCommands(ice.Commands{
ICONS: {Hand: func(m *ice.Message, arg ...string) {
m.Option(lex.SPLIT_SPACE, " {:;}")
m.Cmd(lex.SPLIT, "usr/node_modules/bootstrap-icons/font/bootstrap-icons.css", func(text string, ls []string) {
if len(ls) > 2 && ls[2] == "content" {
ICONS: {Actions: ctx.ConfAction(nfs.PATH, "bootstrap-icons/font/bootstrap-icons.css"), Hand: func(m *ice.Message, arg ...string) {
m.Cmd(lex.SPLIT, ice.USR_MODULES+mdb.Config(m, nfs.PATH), kit.Dict(lex.SPLIT_SPACE, " {:;}"), func(text string, ls []string) {
if len(ls) > 2 && ls[2] == nfs.CONTENT {
name := "bi " + strings.TrimPrefix(ls[0], ".")
m.Push("name", name)
m.Push("icon", kit.Format(`<i class="%s"></i>`, name))
m.Push(mdb.NAME, name).Push(mdb.ICON, kit.Format(`<i class="%s"></i>`, name))
}
})
m.StatusTimeCount()

View File

@ -69,12 +69,12 @@ func init() {
}
switch kit.Select("", arg, 1) {
case web.OPEN:
ctx.ProcessOpen(m, m.Option(mdb.TEXT))
m.ProcessOpen(m.Option(mdb.TEXT))
default:
ctx.ProcessField(m, m.PrefixKey(), []string{m.Option(mdb.TEXT)}, arg...)
}
}},
web.OPEN: {Hand: func(m *ice.Message, arg ...string) { ctx.ProcessOpen(m, m.Option(web.LINK)) }},
web.OPEN: {Hand: func(m *ice.Message, arg ...string) { m.ProcessOpen(m.Option(web.LINK)) }},
web.DREAM_CREATE: {Hand: func(m *ice.Message, arg ...string) {
m.Cmd("", mdb.CREATE, kit.Dict(web.LINK, m.MergePod(m.Option(mdb.NAME))))
}},

View File

@ -136,7 +136,7 @@ func init() {
if arg[0] = strings.Split(arg[0], mdb.FS)[0]; !strings.HasSuffix(arg[0], nfs.PS) && len(arg) == 1 {
arg[1] = kit.Slice(strings.Split(arg[0], nfs.PS), -1)[0]
arg[0] = strings.TrimSuffix(arg[0], arg[1])
ctx.ProcessRewrite(m, nfs.PATH, arg[0], nfs.FILE, arg[1])
m.ProcessRewrite(nfs.PATH, arg[0], nfs.FILE, arg[1])
} else if len(arg) < 2 {
nfs.Dir(m, nfs.PATH)
} else {

View File

@ -49,7 +49,7 @@ func _vimer_make(m *ice.Message, dir string, msg *ice.Message) {
const VIMER = "vimer"
func init() {
web.Index.MergeCommands(ice.Commands{
web.Index.MergeCommands(ice.Commands{ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { aaa.White(m, nfs.REQUIRE) }},
ice.REQUIRE_SRC: {Actions: ctx.CmdAction(), Hand: func(m *ice.Message, arg ...string) { web.ShareLocalFile(m, ice.SRC, path.Join(arg...)) }},
ice.REQUIRE_USR: {Hand: func(m *ice.Message, arg ...string) { web.ShareLocalFile(m, ice.USR, path.Join(arg...)) }},
ice.REQUIRE_MODULES: {Hand: func(m *ice.Message, arg ...string) {

View File

@ -14,6 +14,7 @@ import (
"shylinux.com/x/icebergs/base/nfs"
"shylinux.com/x/icebergs/base/ssh"
"shylinux.com/x/icebergs/base/web"
"shylinux.com/x/icebergs/base/web/html"
"shylinux.com/x/icebergs/misc/xterm"
kit "shylinux.com/x/toolkits"
)
@ -67,7 +68,7 @@ func _xterm_echo(m *ice.Message, h string, str string) {
}
func _xterm_cmds(m *ice.Message, h string, cmd string, arg ...ice.Any) {
kit.If(cmd != "", func() { _xterm_get(m, h).Writeln(cmd, arg...) })
ctx.ProcessHold(m)
m.ProcessHold()
}
const XTERM = "xterm"
@ -103,7 +104,7 @@ func init() {
case nfs.FILE:
push := func(arg ...string) { m.Push(nfs.FILE, strings.Join(arg, nfs.DF)) }
m.Cmd("", func(value ice.Maps) {
kit.If(value[mdb.TYPE] == web.LAYOUT, func() { push(web.LAYOUT, value[mdb.HASH], value[mdb.NAME]) })
kit.If(value[mdb.TYPE] == html.LAYOUT, func() { push(html.LAYOUT, value[mdb.HASH], value[mdb.NAME]) })
})
m.Cmd("", mdb.INPUTS, mdb.TYPE, func(value ice.Maps) { push(ssh.SHELL, value[mdb.TYPE]) })
m.Cmd(nfs.CAT, kit.HomePath(".bash_history"), func(text string) { push(text) })
@ -114,16 +115,16 @@ func init() {
mdb.CREATE: {Hand: func(m *ice.Message, arg ...string) {
m.ProcessRewrite(mdb.HASH, mdb.HashCreate(m, arg))
}},
web.RESIZE: {Hand: func(m *ice.Message, arg ...string) {
html.RESIZE: {Hand: func(m *ice.Message, arg ...string) {
_xterm_get(m, "").Setsize(m.OptionDefault("rows", "24"), m.OptionDefault("cols", "80"))
}},
web.INPUT: {Hand: func(m *ice.Message, arg ...string) {
html.INPUT: {Hand: func(m *ice.Message, arg ...string) {
if b, e := base64.StdEncoding.DecodeString(strings.Join(arg, "")); !m.Warn(e) {
_xterm_get(m, "").Write(b)
}
}},
web.OUTPUT: {Help: "全屏", Hand: func(m *ice.Message, arg ...string) {
web.ProcessPodCmd(m, "", "", m.OptionSimple(mdb.HASH), ctx.STYLE, web.OUTPUT)
html.OUTPUT: {Help: "全屏", Hand: func(m *ice.Message, arg ...string) {
web.ProcessPodCmd(m, "", "", m.OptionSimple(mdb.HASH), ctx.STYLE, html.OUTPUT)
}},
web.DREAM_TABLES: {Hand: func(m *ice.Message, arg ...string) {
kit.Switch(m.Option(mdb.TYPE), kit.Simple(web.SERVER, web.WORKER), func() { m.PushButton(kit.Dict(m.CommandKey(), "终端")) })
@ -138,7 +139,7 @@ func init() {
}},
"install": {Help: "安装", Hand: func(m *ice.Message, arg ...string) {
_xterm_get(m, kit.Select("", arg, 0)).Write([]byte(m.Cmdx(PUBLISH, ice.CONTEXTS, ice.APP, kit.Dict("format", "raw")) + ice.NL))
ctx.ProcessHold(m)
m.ProcessHold()
}},
"terminal": {Help: "本机", Hand: func(m *ice.Message, arg ...string) {
if h := kit.Select(m.Option(mdb.HASH), arg, 0); h == "" {
@ -154,7 +155,7 @@ func init() {
if m.Length() == 0 {
m.Action(mdb.CREATE)
} else {
m.PushAction(web.OUTPUT, mdb.REMOVE).Action(mdb.CREATE, mdb.PRUNES, "terminal")
m.PushAction(html.OUTPUT, mdb.REMOVE).Action(mdb.CREATE, mdb.PRUNES, "terminal")
}
} else {
if m.Length() == 0 {

14
data.go
View File

@ -2,7 +2,6 @@ package ice
import (
"os"
"path"
"strings"
kit "shylinux.com/x/toolkits"
@ -10,14 +9,9 @@ import (
func (m *Message) ActionKey() string { return strings.TrimPrefix(strings.TrimSuffix(m._sub, PS), PS) }
func (m *Message) CommandKey() string { return strings.TrimPrefix(strings.TrimSuffix(m._key, PS), PS) }
func (m *Message) PrefixKey(arg ...string) string {
return kit.Keys(m.Prefix(m.CommandKey()), kit.Keys(arg))
}
func (m *Message) PrefixPath(arg ...Any) string {
return strings.TrimPrefix(path.Join(kit.ReplaceAll(m.Prefix(m._key, kit.Keys(arg...)), PT, PS)), WEB) + PS
}
func (m *Message) PrefixKey() string { return m.Prefix(m.CommandKey()) }
func (m *Message) Prefix(arg ...string) string { return m.Target().Prefix(arg...) }
func (m *Message) Confv(arg ...Any) (val Any) {
func (m *Message) Confv(arg ...Any) (val Any) { // key sub value
run := func(conf *Config) {
if len(arg) == 1 {
val = conf.Value
@ -54,9 +48,7 @@ func SaveImportant(m *Message, arg ...string) {
func loadImportant(m *Message) {
if f, e := os.Open(VAR_DATA_IMPORTANT); e == nil {
defer f.Close()
kit.For(f, func(s string) {
kit.If(s != "" && !strings.HasPrefix(s, "# "), func() { m.Cmd(kit.Split(s)) })
})
kit.For(f, func(s string) { kit.If(s != "" && !strings.HasPrefix(s, "# "), func() { m.Cmd(kit.Split(s)) }) })
}
Info.Important = true
}

42
exec.go
View File

@ -5,7 +5,6 @@ import (
"io"
"reflect"
"strings"
"sync"
"time"
kit "shylinux.com/x/toolkits"
@ -13,23 +12,23 @@ import (
"shylinux.com/x/toolkits/task"
)
func (m *Message) TryCatch(msg *Message, catch bool, cb ...func(msg *Message)) {
func (m *Message) TryCatch(catch bool, cb ...func(*Message)) {
defer func() {
switch e := recover(); e {
case io.EOF, nil:
default:
fileline := m.FormatStack(2, 1)
m.Log(LOG_WARN, "catch: %s %s", e, fileline).Log("chain", msg.FormatChain())
m.Log(LOG_WARN, "catch: %s %s", e, fileline).Log("chain", m.FormatChain())
m.Log(LOG_WARN, "catch: %s %s", e, kit.FileLine(4, 10)).Log("stack", m.FormatStack(2, 1000))
m.Log(LOG_WARN, "catch: %s %s", e, fileline).Result(ErrWarn, e, SP, m.FormatStack(2, 5))
if len(cb) > 1 {
m.TryCatch(msg, catch, cb[1:]...)
m.TryCatch(catch, cb[1:]...)
} else if !catch {
m.Assert(e)
}
}
}()
kit.If(len(cb) > 0, func() { cb[0](msg) })
kit.If(len(cb) > 0, func() { cb[0](m) })
}
func (m *Message) Assert(expr Any) bool {
switch e := expr.(type) {
@ -63,16 +62,14 @@ func (m *Message) GoSleep(t string, arg ...Any) {
}
func (m *Message) Go(cb func(), arg ...Any) *Message {
kit.If(len(arg) == 0, func() { arg = append(arg, logs.FileLine(cb)) })
task.Put(arg[0], func(task *task.Task) { m.TryCatch(m, true, func(m *Message) { cb() }) })
task.Put(arg[0], func(task *task.Task) { m.TryCatch(true, func(m *Message) { cb() }) })
return m
}
func (m *Message) Wait(cb ...Handler) (wait func(), done Handler) {
wg := sync.WaitGroup{}
wg.Add(1)
t := time.AfterFunc(kit.Duration("180s"), func() { wg.Done() })
return func() { wg.Wait() }, func(msg *Message, arg ...string) {
defer wg.Done()
defer t.Stop()
func (m *Message) Wait(d string, cb ...Handler) (wait func() bool, done Handler) {
sync := make(chan bool, 2)
t := time.AfterFunc(kit.Duration(d), func() { sync <- false })
return func() bool { return <-sync }, func(msg *Message, arg ...string) {
defer func() { t.Stop(); sync <- true }()
kit.If(len(cb) > 0 && cb[0] != nil, func() { cb[0](msg, arg...) }, func() { m.Copy(msg) })
}
}
@ -89,6 +86,13 @@ func (m *Message) Cmdx(arg ...Any) string {
return kit.Select("", res, res != strings.TrimSpace(ErrWarn))
}
func (m *Message) Cmdy(arg ...Any) *Message { return m.Copy(m._command(arg...)) }
func (m *Message) CmdList(arg ...string) []string {
msg, list := m._command(arg), []string{}
kit.For(msg._cmd.List, func(value Map) {
kit.If(!kit.IsIn(kit.Format(kit.Value(value, TYPE)), "button"), func() { list = append(list, kit.Format(kit.Value(value, NAME))) })
})
return msg.Appendv(kit.Select(kit.Select("", list, 0), list, len(arg)-1))
}
func (m *Message) CmdHand(cmd *Command, key string, arg ...string) *Message {
if m._cmd, m._key, m._sub = cmd, key, LIST; cmd == nil {
return m
@ -106,13 +110,6 @@ func (m *Message) CmdHand(cmd *Command, key string, arg ...string) *Message {
}
return m
}
func (m *Message) CmdList(arg ...string) []string {
msg, list := m.Cmd(arg), []string{}
kit.For(msg._cmd.List, func(value Map) {
kit.If(!kit.IsIn(kit.Format(kit.Value(value, TYPE)), "button"), func() { list = append(list, kit.Format(kit.Value(value, NAME))) })
})
return msg.Appendv(kit.Select(kit.Select("", list, 0), list, len(arg)-1))
}
func (m *Message) ActionHand(cmd *Command, key, sub string, arg ...string) *Message {
if action, ok := cmd.Actions[sub]; !m.Warn(!ok, ErrNotFound, sub, cmd.FileLines()) {
return m.Target()._action(m, cmd, key, sub, action, arg...)
@ -146,7 +143,7 @@ func (m *Message) _command(arg ...Any) *Message {
}
}
}
if count := kit.Int(m.Option(MSG_COUNT, kit.Format(kit.Int(m.Option(MSG_COUNT))+1))); m.Warn(count > 30000, ErrTooDeepCount) {
if count := kit.Int(m.Option(MSG_COUNT, kit.Format(kit.Int(m.Option(MSG_COUNT))+1))); m.Warn(count > 3000, ErrTooDeepCount) {
panic(count)
}
list := kit.Simple(args...)
@ -156,8 +153,7 @@ func (m *Message) _command(arg ...Any) *Message {
}
ok := false
run := func(msg *Message, ctx *Context, cmd *Command, key string, arg ...string) {
ok = true
msg._source = _source
ok, msg._source = true, _source
key = kit.Slice(strings.Split(key, PT), -1)[0]
kit.If(cbs, func() { msg.OptionCB(key, cbs) })
kit.For(opts, func(k string, v Any) { msg.Option(k, v) })

32
info.go
View File

@ -27,9 +27,9 @@ type MakeInfo struct {
When string
Message string
Domain string
Module string
System string
Domain string
}
func (s MakeInfo) Versions() string {
@ -67,16 +67,17 @@ var Info = struct {
Gomod Maps
Route Maps
Index Map
Stack map[string]func(m *Message, key string, arg ...Any) Any
merges []Any
render map[string]func(*Message, ...Any) string
OpenFile func(m *Message, p string) (io.ReadCloser, error)
Stack map[string]func(m *Message, key string, arg ...Any) Any
Inputs []func(m *Message, arg ...string)
PushStream func(m *Message)
PushNotice func(m *Message, arg ...Any)
Inputs []func(m *Message, arg ...string)
Load func(m *Message, key ...string) *Message
Save func(m *Message, key ...string) *Message
Load func(m *Message, key ...string) *Message
Open func(m *Message, p string) (io.ReadCloser, error)
Log func(m *Message, p, l, s string)
}{
Localhost: true,
@ -85,19 +86,21 @@ var Info = struct {
Gomod: Maps{},
Route: Maps{},
Index: Map{},
Stack: map[string]func(m *Message, key string, arg ...Any) Any{},
render: map[string]func(*Message, ...Any) string{},
OpenFile: func(m *Message, p string) (io.ReadCloser, error) { return miss.OpenFile(p) },
Stack: map[string]func(m *Message, key string, arg ...Any) Any{},
PushStream: func(m *Message) {},
PushNotice: func(m *Message, arg ...Any) {},
Load: func(m *Message, key ...string) *Message { return m },
Save: func(m *Message, key ...string) *Message { return m },
Load: func(m *Message, key ...string) *Message { return m },
Open: func(m *Message, p string) (io.ReadCloser, error) { return miss.OpenFile(p) },
Log: func(m *Message, p, l, s string) {},
}
func AddMergeAction(h ...Any) { Info.merges = append(Info.merges, h...) }
func AddMergeAction(h ...Any) {
Info.merges = append(Info.merges, h...)
}
func MergeHand(hand ...Handler) Handler {
if len(hand) == 0 {
return nil
@ -118,9 +121,7 @@ func MergeActions(arg ...Any) Actions {
return nil
}
list := arg[0].(Actions)
if list == nil {
list = Actions{}
}
kit.If(list == nil, func() { list = Actions{} })
for _, from := range arg[1:] {
switch from := from.(type) {
case Actions:
@ -137,10 +138,7 @@ func MergeActions(arg ...Any) Actions {
}
case string:
h := list[CTX_INIT]
if h == nil {
list[CTX_INIT] = &Action{}
h = list[CTX_INIT]
}
kit.If(h == nil, func() { list[CTX_INIT] = &Action{}; h = list[CTX_INIT] })
h.Hand = MergeHand(h.Hand, func(m *Message, arg ...string) {
_cmd := m._cmd
m.Search(from, func(p *Context, s *Context, key string, cmd *Command) {

24
init.go
View File

@ -25,10 +25,11 @@ func (s *Frame) Begin(m *Message, arg ...string) {
}
func (s *Frame) Start(m *Message, arg ...string) {
m.Cmd(INIT, arg)
kit.For(kit.Split(kit.Select(kit.Join([]string{LOG, GDB, SSH}), os.Getenv(CTX_DAEMON))), func(k string) { m.Sleep("10ms").Start(k) })
m.Sleep("10ms").Cmd(arg)
kit.For([]string{LOG, GDB, SSH}, func(k string) { m.Sleep30ms().Start(k) })
m.Sleep30ms().Cmd(arg)
}
func (s *Frame) Close(m *Message, arg ...string) {
defer conf.Close()
list := map[*Context]*Message{m.target: m}
m.Travel(func(p *Context, s *Context) {
if msg, ok := list[p]; ok && msg != nil {
@ -36,8 +37,7 @@ func (s *Frame) Close(m *Message, arg ...string) {
s.Close(list[s], arg...)
}
})
conf.Close()
go func() { os.Exit(kit.Int(Pulse.Sleep30ms().Option(EXIT))) }()
go func() { os.Exit(kit.Int(Pulse.Sleep300ms().Option(EXIT))) }()
}
const (
@ -59,14 +59,11 @@ var Index = &Context{Name: ICE, Help: "冰山模块", Commands: Commands{
loadImportant(m)
}},
QUIT: {Hand: func(m *Message, arg ...string) {
m.Go(func() {
m.Sleep("10ms")
os.Exit(0)
})
m.Go(func() { m.Sleep30ms(); os.Exit(0) })
}},
EXIT: {Hand: func(m *Message, arg ...string) {
m.Go(func() {
m.Sleep("10ms")
m.Sleep30ms()
m.root.Option(EXIT, kit.Select("0", arg, 0))
m.Cmd(SOURCE, ETC_EXIT_SHY)
m.Cmd(CTX_EXIT)
@ -83,23 +80,22 @@ var Index = &Context{Name: ICE, Help: "冰山模块", Commands: Commands{
var Pulse = &Message{meta: map[string][]string{}, data: Map{}, source: Index, target: Index}
func init() {
Index.root, Pulse.root = Index, Pulse
switch tz := os.Getenv("TZ"); tz {
case "", "Asia/Beijing", "Asia/Shanghai":
time.Local = time.FixedZone(tz, 28800)
}
Pulse.time = time.Now()
Index.root, Pulse.root, Pulse.time = Index, Pulse, time.Now()
}
func Run(arg ...string) string {
kit.If(len(arg) == 0 && len(os.Args) > 1, func() { arg = kit.Simple(os.Args[1:], kit.Split(kit.Env(CTX_ARG))) })
kit.If(len(arg) == 0 && len(os.Args) > 1, func() { arg = os.Args[1:] })
if len(arg) == 0 {
if runtime.GOOS == "windows" {
if runtime.GOOS == WINDOWS {
arg = append(arg, SERVE, START)
} else {
arg = append(arg, FOREVER, START)
}
} else if arg[0] == FOREVER && arg[1] == START && runtime.GOOS == "windows" {
} else if arg[0] == FOREVER && arg[1] == START && runtime.GOOS == WINDOWS {
arg[0] = SERVE
}
Pulse.meta[MSG_DETAIL] = arg

View File

@ -65,7 +65,6 @@ func (m *Message) log(level string, str string, arg ...Any) *Message {
prefix, suffix = "\033[31m", "\033[0m"
}
}
kit.If(level == LOG_INFO && len(str) > 4096, func() { 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
}
@ -114,8 +113,9 @@ func (m *Message) Warn(err Any, arg ...Any) bool {
kit.If(map[string]int{
ErrNotLogin: http.StatusUnauthorized,
ErrNotRight: http.StatusForbidden,
ErrNotFound: http.StatusNotFound,
ErrNotAllow: http.StatusMethodNotAllowed,
ErrNotValid: http.StatusBadRequest,
ErrNotFound: http.StatusNotFound,
}[kit.Format(arg[0])], func(s int) { m.Render(RENDER_STATUS, s, str) })
}
return true
@ -147,9 +147,7 @@ func (m *Message) IsOk() bool { return m.Result() == OK }
func (m *Message) IsErr(arg ...string) bool {
return len(arg) == 0 && kit.Select("", m.meta[MSG_RESULT], 0) == ErrWarn || len(arg) > 0 && kit.Select("", m.meta[MSG_RESULT], 1) == arg[0]
}
func (m *Message) IsErrNotFound() bool {
return m.IsErr(ErrNotFound)
}
func (m *Message) IsErrNotFound() bool { return m.IsErr(ErrNotFound) }
func (m *Message) Debug(str string, arg ...Any) {
kit.Format(str == "", func() { str = m.FormatMeta() })
m.log(LOG_DEBUG, str, arg...)

21
meta.go
View File

@ -156,25 +156,10 @@ func (m *Message) Push(key string, value Any, arg ...Any) *Message {
func (m *Message) EchoLine(str string, arg ...Any) *Message {
return m.Echo(str, arg...).Echo(NL)
}
func PushNotice(m *Message, arg ...Any) bool {
if m.Option(MSG_DAEMON) == "" {
return false
} else if m.Option(MSG_USERPOD) == "" {
m.Cmd("web.space", m.Option(MSG_DAEMON), arg, Maps{MSG_OPTION: "", MSG_OPTS: ""})
} else {
// m.Cmd("web.spide", OPS, MergeURL2(m, "/share/toast/"+m.Option(MSG_DAEMON)), ARG, kit.Format(arg))
}
return true
}
func (m *Message) Echo(str string, arg ...Any) *Message {
if str == "" {
return m
}
// if m.Option("output.stream") == "grow" {
// if PushNotice(m, "grow", kit.Format(str, arg...)) {
// return m
// }
// }
return m.Add(MSG_RESULT, kit.Format(str, arg...))
}
func (m *Message) Copy(msg *Message, arg ...string) *Message {
@ -292,11 +277,9 @@ func (m *Message) TableEchoWithStatus() *Message {
m.TableEcho()
list := []string{}
kit.For(kit.UnMarshal(m.Option(MSG_STATUS)), func(index int, value Map) {
list = append(list, kit.Format("%s: %s", value[NAME], value[VALUE]))
kit.If(value[VALUE] != nil, func() { list = append(list, kit.Format("%s: %s", value[NAME], value[VALUE])) })
})
if len(list) > 0 {
m.Echo(strings.Join(list, SP)).Echo(NL)
}
kit.If(len(list) > 0, func() { m.Echo(strings.Join(list, SP)).Echo(NL) })
return m
}

View File

@ -12,8 +12,7 @@ func (m *Message) IsEnglish() bool {
func (m *Message) Split(str string, arg ...string) *Message {
m.Set(MSG_APPEND).Set(MSG_RESULT)
field := kit.Select("", arg, 0)
sp := kit.Select(SP, arg, 1)
nl := kit.Select(NL, arg, 2)
sp, nl := kit.Select(SP, arg, 1), kit.Select(NL, arg, 2)
fields, indexs := kit.Split(field, sp, sp, sp), []int{}
for i, l := range kit.Split(str, nl, nl, nl) {
if strings.HasPrefix(l, "Binary") {
@ -148,3 +147,6 @@ func (m *Message) CmdMap(arg ...string) map[string]map[string]string {
m._command(kit.Slice(arg, 0, -1)).Table(func(value Maps) { list[value[field]] = value })
return list
}
func (m *Message) Toast(content string, arg ...string) { // title duration
Info.PushNotice(m, "toast", content, arg)
}

View File

@ -112,7 +112,5 @@ func (m *Message) ProcessHold(text ...Any) { m.Process(PROCESS_HOLD, text...)
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) {
kit.If(url, func() { m.Process(PROCESS_OPEN, url) })
}
func (m *Message) ProcessOpen(url string) { kit.If(url, func() { m.Process(PROCESS_OPEN, url) }) }
func (m *Message) ProcessClose() { m.Process(PROCESS_CLOSE) }

View File

@ -216,6 +216,6 @@ func (m *Message) resource(file string) string {
if p = strings.TrimPrefix(p, kit.Path("")+PS); strings.Contains(p, "/pkg/mod/") {
p = strings.Split(p, "/pkg/mod/")[1]
}
kit.If(file == "", func() { p = kit.ExtChange(p, "js") }, func() { p = path.Join(path.Dir(p), file) })
kit.If(file == "", func() { p = kit.ExtChange(p, JS) }, func() { p = path.Join(path.Dir(p), file) })
return kit.MergeURL("/require/"+p, POD, m.Option(MSG_USERPOD))
}

10
type.go
View File

@ -174,7 +174,7 @@ func (c *Context) Merge(s *Context) *Context {
kit.If(action.List == nil, func() { action.List = SplitCmd(action.Name, nil) })
kit.If(len(action.List) > 0, func() { cmd.Meta[sub] = action.List })
}
kit.If(cmd.Name == "", func() { cmd.Name = "list path auto" })
kit.If(cmd.Name == "", func() { cmd.Name = "list list" })
kit.If(strings.HasPrefix(cmd.Name, "list"), func() { cmd.Name = strings.Replace(cmd.Name, "list", key, 1) })
kit.If(cmd.List == nil, func() { cmd.List = SplitCmd(cmd.Name, cmd.Actions) })
}
@ -400,9 +400,5 @@ func (m *Message) Design(action Any, help string, input ...Any) {
kit.Value(m._cmd.Meta, kit.Keys("_trans", k), help)
}
}
func (m *Message) Actions(key string) *Action {
return m._cmd.Actions[key]
}
func (m *Message) Commands(key string) *Command {
return m.Target().Commands[kit.Select(m._key, key)]
}
func (m *Message) Actions(key string) *Action { return m._cmd.Actions[key] }
func (m *Message) Commands(key string) *Command { return m.Target().Commands[kit.Select(m._key, key)] }