diff --git a/base/cli/runtime.go b/base/cli/runtime.go index 09688943..9b7307bc 100644 --- a/base/cli/runtime.go +++ b/base/cli/runtime.go @@ -203,3 +203,4 @@ func NodeInfo(m *ice.Message, arg ...string) { ice.Info.NodeName = mdb.Conf(m, RUNTIME, kit.Keys(NODE, mdb.NAME), kit.Select(ice.Info.NodeName, arg, 0)) ice.Info.NodeType = mdb.Conf(m, RUNTIME, kit.Keys(NODE, mdb.TYPE), kit.Select(ice.Info.NodeType, arg, 1)) } +func IsWindows() bool { return runtime.GOOS == WINDOWS } diff --git a/base/mdb/hash.go b/base/mdb/hash.go index 4b4f7afa..666c072d 100644 --- a/base/mdb/hash.go +++ b/base/mdb/hash.go @@ -125,9 +125,8 @@ const HASH = "hash" func HashAction(arg ...Any) ice.Actions { return ice.Actions{ice.CTX_INIT: AutoConfig(append(kit.List(FIELD, HASH_FIELD), arg...)...), - ice.CTX_EXIT: {Hand: func(m *ice.Message, arg ...string) { - HashSelectClose(m) - }}, + ice.CTX_EXIT: {Hand: func(m *ice.Message, arg ...string) { HashSelectClose(m) }}, + INPUTS: {Hand: func(m *ice.Message, arg ...string) { HashInputs(m, arg) }}, CREATE: {Hand: func(m *ice.Message, arg ...string) { HashCreate(m, arg) }}, REMOVE: {Hand: func(m *ice.Message, arg ...string) { HashRemove(m, arg) }}, diff --git a/base/mdb/lock.go b/base/mdb/lock.go index 425b26c4..cc72adff 100644 --- a/base/mdb/lock.go +++ b/base/mdb/lock.go @@ -10,7 +10,7 @@ import ( type configMessage interface { Option(key string, arg ...Any) string - PrefixKey() string + PrefixKey(...string) string Confv(...Any) Any } @@ -19,7 +19,6 @@ var _locks = map[string]*task.Lock{} func getLock(m configMessage, arg ...string) *task.Lock { key := kit.Select(m.PrefixKey(), kit.Keys(arg)) - m.Option("_lock", key) defer _lock.Lock()() l, ok := _locks[key] if !ok { @@ -67,7 +66,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 add == nil { + if key = m.PrefixKey(key); add == nil { cache.Delete(key) return nil } diff --git a/base/mdb/search.go b/base/mdb/search.go index 48a8a886..c4cf78b0 100644 --- a/base/mdb/search.go +++ b/base/mdb/search.go @@ -6,7 +6,7 @@ const SEARCH = "search" func init() { Index.MergeCommands(ice.Commands{SEARCH: {Help: "搜索", Actions: RenderAction()}}) - ice.AddMerges(func(c *ice.Context, key string, cmd *ice.Command, sub string, action *ice.Action) ice.Handler { + ice.AddMergeAction(func(c *ice.Context, key string, cmd *ice.Command, sub string, action *ice.Action) ice.Handler { if sub == SEARCH { return func(m *ice.Message, arg ...string) { m.Cmd(sub, CREATE, m.CommandKey(), m.PrefixKey()) } } diff --git a/base/nfs/cat.go b/base/nfs/cat.go index a89f9147..5121548d 100644 --- a/base/nfs/cat.go +++ b/base/nfs/cat.go @@ -165,7 +165,7 @@ func OptionLoad(m *ice.Message, file string) *ice.Message { type templateMessage interface { Cmdx(arg ...ice.Any) string - PrefixKey() string + PrefixKey(...string) string } func Template(m templateMessage, file string, arg ...ice.Any) string { diff --git a/base/nfs/dir.go b/base/nfs/dir.go index 950fba1f..13278814 100644 --- a/base/nfs/dir.go +++ b/base/nfs/dir.go @@ -237,9 +237,9 @@ func Dir(m *ice.Message, sort string) *ice.Message { 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, "") - if msg := m.Cmd(DIR, dir, arg).Table(cb); cb == nil { + if msg := m.Cmd(DIR, dir, arg); cb == nil { return m.Copy(msg) } else { - return msg + return msg.Table(cb) } } diff --git a/base/ssh/script.go b/base/ssh/script.go index c10a4cf7..83bee485 100644 --- a/base/ssh/script.go +++ b/base/ssh/script.go @@ -103,9 +103,9 @@ func (f *Frame) parse(m *ice.Message, h, line string) string { return "" } func (f *Frame) scan(m *ice.Message, h, line string) *Frame { + kit.If(f.source == STDIO, func() { m.Options(MESSAGE, m, ice.LOG_DISABLE, ice.TRUE) }) f.ps1 = kit.Simple(mdb.Confv(m, PROMPT, kit.Keym(PS1))) f.ps2 = kit.Simple(mdb.Confv(m, PROMPT, kit.Keym(PS2))) - m.Options(MESSAGE, m, ice.LOG_DISABLE, ice.TRUE) m.I, m.O = f.stdin, f.stdout ps, bio := f.ps1, bufio.NewScanner(f.stdin) for f.prompt(m, ps...); f.stdin != nil && bio.Scan(); f.prompt(m, ps...) { diff --git a/base/web/cache.go b/base/web/cache.go index 257e0463..9d50e7d9 100644 --- a/base/web/cache.go +++ b/base/web/cache.go @@ -131,7 +131,7 @@ func init() { }}, ice.RENDER_DOWNLOAD: {Hand: func(m *ice.Message, arg ...string) { p := kit.Select(arg[0], arg, 1) - p = kit.Select("", SHARE_LOCAL, !strings.HasPrefix(p, ice.PS) && !strings.HasPrefix(p, ice.HTTP)) + p + p = kit.Select("", SHARE_LOCAL, !strings.HasPrefix(p, ice.PS) && !strings.HasPrefix(p, HTTP)) + p args := []string{ice.POD, m.Option(ice.MSG_USERPOD), "filename", kit.Select("", arg[0], len(arg) > 1)} m.Echo(fmt.Sprintf(`%s`, MergeURL2(m, p, args), path.Base(arg[0]), arg[0])) }}, @@ -155,7 +155,7 @@ func init() { } }}, }) - ice.AddMerges(func(c *ice.Context, key string, cmd *ice.Command, sub string, action *ice.Action) { + ice.AddMergeAction(func(c *ice.Context, key string, cmd *ice.Command, sub string, action *ice.Action) { switch sub { case UPLOAD: if c.Name == WEB && key == CACHE { diff --git a/base/web/option.go b/base/web/option.go index f6346edd..ec86d4be 100644 --- a/base/web/option.go +++ b/base/web/option.go @@ -112,7 +112,7 @@ func PushPodCmd(m *ice.Message, cmd string, arg ...string) { type Message interface { Option(key string, arg ...ice.Any) string - PrefixKey() string + PrefixKey(...string) string } func OptionAgentIs(m Message, arg ...string) bool { @@ -128,7 +128,7 @@ func OptionUserWeb(m Message) *url.URL { } func MergeURL2(m Message, url string, arg ...ice.Any) string { if m.Option(ice.MSG_USERWEB) == "" { - return kit.MergeURL2(ice.HTTP+"://"+ice.Pulse.Cmd(tcp.HOST).Append(aaa.IP)+":"+ice.Pulse.Cmd(SERVE).Append(tcp.PORT), url, arg...) + return kit.MergeURL2(HTTP+"://"+ice.Pulse.Cmd(tcp.HOST).Append(aaa.IP)+":"+ice.Pulse.Cmd(SERVE).Append(tcp.PORT), url, arg...) } return kit.MergeURL2(m.Option(ice.MSG_USERWEB), url, arg...) } diff --git a/base/web/render.go b/base/web/render.go index 2c9d0c2f..ba77ae9a 100644 --- a/base/web/render.go +++ b/base/web/render.go @@ -38,7 +38,7 @@ func Render(m *ice.Message, cmd string, args ...ice.Any) bool { case ice.RENDER_REDIRECT: // url [arg...] http.Redirect(m.W, m.R, kit.MergeURL(arg[0], arg[1:]), http.StatusTemporaryRedirect) case ice.RENDER_DOWNLOAD: // file [type [name]] - if strings.HasPrefix(arg[0], ice.HTTP) { + if strings.HasPrefix(arg[0], HTTP) { RenderRedirect(m, arg[0]) break } diff --git a/base/web/serve.go b/base/web/serve.go index 497e64a0..390c3525 100644 --- a/base/web/serve.go +++ b/base/web/serve.go @@ -5,16 +5,12 @@ import ( "net/url" "path" "regexp" - "runtime" "strings" - "sync" - "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/gdb" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" "shylinux.com/x/icebergs/base/ssh" @@ -29,7 +25,7 @@ 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) }) kit.If(m.Option(aaa.USERNAME), func() { aaa.UserRoot(m, m.Option(aaa.USERNICK), m.Option(aaa.USERNAME)) }) kit.If(m.Option(tcp.PORT) == tcp.RANDOM, func() { m.Option(tcp.PORT, m.Cmdx(tcp.PORT, aaa.RIGHT)) }) - kit.If(runtime.GOOS == cli.WINDOWS, func() { m.Cmd(SPIDE, ice.OPS, _serve_address(m)+"/exit").Sleep300ms() }) + kit.If(cli.IsWindows(), func() { m.Cmd(SPIDE, ice.OPS, _serve_address(m)+"/exit").Sleep300ms() }) cli.NodeInfo(m, kit.Select(ice.Info.Hostname, m.Option(tcp.NODENAME)), SERVER) m.Target().Start(m, m.OptionSimple(tcp.HOST, tcp.PORT)...) } @@ -77,34 +73,23 @@ func _serve_handle(key string, cmd *ice.Command, m *ice.Message, w http.Response } kit.For(u.Query(), func(k string, v []string) { _log(ctx.ARGS, k, v).Optionv(k, v) }) } - m.Options(ice.MSG_USERUA, r.Header.Get(UserAgent)) - for k, v := range kit.ParseQuery(r.URL.RawQuery) { - kit.If(m.IsCliUA(), func() { v = kit.Simple(v, func(v string) (string, error) { return url.QueryUnescape(v) }) }) - m.Optionv(k, v) - } + kit.For(kit.ParseQuery(r.URL.RawQuery), func(k string, v []string) { m.Optionv(k, v) }) switch r.Header.Get(ContentType) { - case ContentJSON: - data := kit.UnMarshal(r.Body) - _log("Body", mdb.VALUE, kit.Format(data)).Optionv(ice.MSG_USERDATA, data) - kit.For(data, func(k string, v ice.Any) { m.Optionv(k, v) }) + case ApplicationJSON: + kit.For(kit.UnMarshal(r.Body), func(k string, v ice.Any) { m.Optionv(k, v) }) default: r.ParseMultipartForm(kit.Int64(kit.Select("4096", r.Header.Get(ContentLength)))) - kit.For(r.PostForm, func(k string, v []string) { - kit.If(m.IsCliUA(), func() { v = kit.Simple(v, func(v string) (string, error) { return url.QueryUnescape(v) }) }) - _log("Form", k, kit.Join(v, ice.SP)).Optionv(k, v) - }) + kit.For(r.PostForm, func(k string, v []string) { _log(FORM, k, kit.Join(v, ice.SP)).Optionv(k, v) }) } kit.For(r.Cookies(), func(k, v string) { m.Optionv(k, v) }) m.OptionDefault(ice.MSG_HEIGHT, "480", ice.MSG_WIDTH, "320") 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))))) - m.Options(ice.MSG_USERIP, r.Header.Get(ice.MSG_USERIP), ice.MSG_USERADDR, kit.Select(r.RemoteAddr, r.Header.Get(ice.MSG_USERADDR))) - if m.Optionv(ice.MSG_CMDS) == nil { - if p := strings.TrimPrefix(r.URL.Path, key); p != "" { - m.Optionv(ice.MSG_CMDS, strings.Split(p, ice.PS)) - } - } - if cmds, ok := _serve_login(m, key, kit.Simple(m.Optionv(ice.MSG_CMDS)), w, r); ok { + kit.If(m.Optionv(ice.MSG_CMDS) == nil, func() { + kit.If(strings.TrimPrefix(r.URL.Path, key), func(p string) { m.Optionv(ice.MSG_CMDS, strings.Split(p, ice.PS)) }) + }) + 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())) }() 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 { @@ -122,61 +107,49 @@ func _serve_domain(m *ice.Message) string { func() string { return ice.Info.Domain }, func() string { if b, e := regexp.MatchString("^[0-9.]+$", m.R.Host); b && e == nil { - return kit.Format("%s://%s:%s", kit.Select("https", ice.HTTP, m.R.TLS == nil), m.R.Host, m.Option(tcp.PORT)) + return kit.Format("%s://%s:%s", kit.Select(HTTPS, HTTP, m.R.TLS == nil), m.R.Host, m.Option(tcp.PORT)) } - return kit.Format("%s://%s", kit.Select("https", ice.HTTP, m.R.TLS == nil), m.R.Host) + return kit.Format("%s://%s", kit.Select(HTTPS, HTTP, m.R.TLS == nil), m.R.Host) }, ) } - -var localhost = sync.Map{} - -func _serve_login(m *ice.Message, key string, cmds []string, w http.ResponseWriter, r *http.Request) ([]string, bool) { +func _serve_auth(m *ice.Message, key string, cmds []string, w http.ResponseWriter, r *http.Request) ([]string, bool) { if r.URL.Path == PP(SPACE) { return cmds, true } - if aaa.SessCheck(m, m.Option(ice.MSG_SESSID)); m.Option(ice.MSG_USERNAME) == "" { - last, ok := localhost.Load(m.Option(ice.MSG_USERIP)) - if ls := kit.Simple(last); ok && len(ls) > 0 && kit.Time(m.Time())-kit.Time(ls[0]) < int64(time.Hour) { - m.Auth( - aaa.USERNICK, m.Option(ice.MSG_USERNICK, ls[1]), - aaa.USERNAME, m.Option(ice.MSG_USERNAME, ls[2]), - aaa.USERROLE, m.Option(ice.MSG_USERROLE, ls[3]), - "last", ls[0], - ) - } else if ice.Info.Localhost && tcp.IsLocalHost(m, m.Option(ice.MSG_USERIP)) { - aaa.UserRoot(m) - } else { - gdb.Event(m, SERVE_LOGIN) - } - if ice.Info.Localhost { - localhost.Store(m.Option(ice.MSG_USERIP), kit.Simple(m.Time(), m.OptionSplit(ice.MSG_USERNICK, ice.MSG_USERNAME, ice.MSG_USERROLE))) + if aaa.SessCheck(m, m.Option(ice.MSG_SESSID)); m.Option(SHARE) != "" { + switch msg := m.Cmd(SHARE, m.Option(SHARE)); msg.Append(mdb.TYPE) { + case FIELD, STORM: + msg.Table(func(value ice.Maps) { aaa.SessAuth(m, value) }) } } - if _, ok := m.Target().Commands[WEB_LOGIN]; ok { - return cmds, !m.Target().Cmd(m, WEB_LOGIN, kit.Simple(key, cmds)...).IsErr() - } else if gdb.Event(m, SERVE_CHECK, key, cmds); m.IsErr() { - return cmds, false - } else if m.IsOk() { - return cmds, m.SetResult() != nil - } else { - return cmds, aaa.Right(m, key, cmds) + if m.Option(ice.MSG_USERNAME) == "" && ice.Info.Localhost { + ls := kit.Simple(mdb.Cache(m, m.Option(ice.MSG_USERIP), func() ice.Any { + if tcp.IsLocalHost(m, m.Option(ice.MSG_USERIP)) { + aaa.UserRoot(m) + return kit.Simple(m.Time(), m.OptionSplit(ice.MSG_USERNICK, ice.MSG_USERNAME, ice.MSG_USERROLE)) + } + return nil + })) + if len(ls) > 0 { + m.Auth(aaa.USERNICK, m.Option(ice.MSG_USERNICK, ls[1]), aaa.USERNAME, m.Option(ice.MSG_USERNAME, ls[2]), aaa.USERROLE, m.Option(ice.MSG_USERROLE, ls[3]), CACHE, ls[0]) + } } + return cmds, aaa.Right(m, key, cmds) } const ( SERVE_START = "serve.start" - SERVE_LOGIN = "serve.login" - SERVE_CHECK = "serve.check" - REQUIRE_SRC = "require/src/" - REQUIRE_USR = "require/usr/" - REQUIRE_MODULES = "require/modules/" + HTTP = "http" + HTTPS = "https" + DOMAIN = "domain" + INDEX = "index" + FORM = "form" + BODY = "body" + SSO = "sso" - WEB_LOGIN = "_login" - DOMAIN = "domain" - INDEX = "index" - SSO = "sso" + ApplicationJSON = "Application/json" ) const SERVE = "serve" @@ -187,78 +160,31 @@ func init() { ice.Info.Localhost = mdb.Config(m, tcp.LOCALHOST) == ice.TRUE cli.NodeInfo(m, ice.Info.Pathname, WORKER) }}, + 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() { msg := m.Spawn(kit.Dict(ice.LOG_DISABLE, ice.TRUE)).Sleep("10ms") - msg.Cmd(ssh.PRINTF, kit.Dict(nfs.CONTENT, ice.NL+ice.Render(msg, ice.RENDER_QRCODE, tcp.PublishLocalhost(msg, kit.Format("http://localhost:%s", msg.Option(tcp.PORT)))))) - msg.Cmd(ssh.PROMPT) + msg.Cmd(ssh.PRINTF, kit.Dict(nfs.CONTENT, ice.NL+ice.Render(msg, ice.RENDER_QRCODE, tcp.PublishLocalhost(msg, kit.Format("http://localhost:%s", msg.Option(tcp.PORT)))))).Cmd(ssh.PROMPT) opened := false for i := 0; i < 3 && !opened; i++ { - msg.Sleep("1s").Cmd(SPACE, func(values ice.Maps) { kit.If(values[mdb.TYPE] == CHROME, func() { opened = true }) }) + msg.Sleep("1s").Cmd(SPACE, func(value ice.Maps) { kit.If(value[mdb.TYPE] == CHROME, func() { opened = true }) }) } kit.If(!opened, func() { cli.Opens(msg, _serve_address(msg)) }) }) }}, - DOMAIN: {Hand: func(m *ice.Message, arg ...string) { - kit.If(len(arg) > 0, func() { ice.Info.Domain, ice.Info.Localhost = arg[0], false }) - m.Echo(ice.Info.Domain) - }}, }, mdb.HashAction(mdb.SHORT, mdb.NAME, mdb.FIELD, "time,status,name,proto,host,port", tcp.LOCALHOST, ice.TRUE), mdb.ClearOnExitHashAction())}, - PP(ice.PUBLISH): {Name: "/publish/", Help: "定制化", Actions: aaa.WhiteAction(), Hand: func(m *ice.Message, arg ...string) { - _share_local(m, ice.USR_PUBLISH, path.Join(arg...)) - }}, - PP(ice.REQUIRE): {Name: "/require/shylinux.com/x/volcanos/proto.js", Help: "代码库", Hand: func(m *ice.Message, arg ...string) { - if len(arg) < 4 { - m.RenderStatusBadRequest() - return - } else if path.Join(arg[:3]...) == ice.Info.Make.Module && nfs.ExistsFile(m, path.Join(arg[3:]...)) { - m.RenderDownload(path.Join(arg[3:]...)) - return - } - p := path.Join(kit.Select(ice.USR_REQUIRE, m.Cmdx(cli.SYSTEM, "go", "env", "GOMODCACHE")), path.Join(arg...)) - if !nfs.ExistsFile(m, p) { - if p = path.Join(ice.USR_REQUIRE, path.Join(arg...)); !nfs.ExistsFile(m, p) { - ls := strings.SplitN(path.Join(arg[:3]...), ice.AT, 2) - if v := kit.Select(ice.Info.Gomod[ls[0]], ls, 1); v == "" { - m.Cmd(cli.SYSTEM, "git", "clone", "https://"+ls[0], path.Join(ice.USR_REQUIRE, path.Join(arg[:3]...))) - } else { - m.Cmd(cli.SYSTEM, "git", "clone", "-b", v, "https://"+ls[0], path.Join(ice.USR_REQUIRE, path.Join(arg[:3]...))) - } - } - } - m.RenderDownload(p) - }}, - PP(REQUIRE_SRC): {Name: "/require/src/", Help: "源代码", Actions: ice.MergeActions(ctx.CmdAction(), aaa.RoleAction()), Hand: func(m *ice.Message, arg ...string) { - _share_local(m, ice.SRC, path.Join(arg...)) - }}, - PP(REQUIRE_USR): {Name: "/require/usr/", Help: "代码库", Hand: func(m *ice.Message, arg ...string) { - _share_local(m, ice.USR, path.Join(arg...)) - }}, - PP(REQUIRE_MODULES): {Name: "/require/modules/", Help: "依赖库", Hand: func(m *ice.Message, arg ...string) { - p := path.Join(ice.USR_MODULES, path.Join(arg...)) - if !nfs.ExistsFile(m, p) { - m.Cmd(cli.SYSTEM, "npm", "install", arg[0], kit.Dict(cli.CMD_DIR, ice.USR)) - } - m.RenderDownload(p) - }}, }) - ice.AddMerges(func(c *ice.Context, key string, cmd *ice.Command, sub string, action *ice.Action) { + ice.AddMergeAction(func(c *ice.Context, key string, cmd *ice.Command, sub string, action *ice.Action) { if strings.HasPrefix(sub, ice.PS) { - if sub = kit.Select(PP(key, sub), PP(key), sub == ice.PS); action.Hand == nil { - action.Hand = func(m *ice.Message, arg ...string) { m.Cmdy(key, arg) } - } - actions := ice.Actions{} - for k, v := range cmd.Actions { - switch k { - case ctx.COMMAND, ice.RUN: - actions[k] = v - } - } - c.Commands[sub] = &ice.Command{Name: sub, Help: cmd.Help, Actions: actions, Hand: action.Hand} + kit.If(action.Hand == nil, func() { action.Hand = cmd.Hand }) + sub = kit.Select(P(key, sub), PP(key, sub), strings.HasSuffix(sub, ice.PS)) + c.Commands[sub] = &ice.Command{Name: kit.Select(cmd.Name, action.Name), Actions: ctx.CmdAction(), Hand: action.Hand} } }) } -func ServeAction() ice.Actions { return gdb.EventsAction(SERVE_START, SERVE_LOGIN, SERVE_CHECK) } diff --git a/base/web/share.go b/base/web/share.go index f193affa..ac6e645b 100644 --- a/base/web/share.go +++ b/base/web/share.go @@ -19,7 +19,7 @@ import ( ) func _share_link(m *ice.Message, p string) string { - return tcp.PublishLocalhost(m, MergeLink(m, kit.Select("", SHARE_LOCAL, !strings.HasPrefix(p, ice.PS) && !strings.HasPrefix(p, ice.HTTP))+p)) + return tcp.PublishLocalhost(m, MergeLink(m, kit.Select("", SHARE_LOCAL, !strings.HasPrefix(p, ice.PS) && !strings.HasPrefix(p, HTTP))+p)) } func _share_cache(m *ice.Message, arg ...string) { if pod := m.Option(ice.POD); ctx.PodCmd(m, CACHE, arg[0]) { @@ -27,7 +27,7 @@ func _share_cache(m *ice.Message, arg ...string) { m.RenderResult(m.Append(mdb.TEXT)) } else { m.Option(ice.POD, pod) - _share_local(m, m.Append(nfs.FILE)) + ShareLocalFile(m, m.Append(nfs.FILE)) } } else { if m.Cmdy(CACHE, arg[0]); m.Append(nfs.FILE) == "" { @@ -37,37 +37,6 @@ func _share_cache(m *ice.Message, arg ...string) { } } } -func _share_local(m *ice.Message, arg ...string) { - p := path.Join(arg...) - switch ls := strings.Split(p, ice.PS); ls[0] { - case ice.ETC, ice.VAR: - if m.Warn(m.Option(ice.MSG_USERROLE) == aaa.VOID, ice.ErrNotRight, p) { - return - } - default: - if m.Option(ice.POD) == "" && !aaa.Right(m, ls) { - return - } - } - if m.Option(ice.POD) == "" { - m.RenderDownload(p) - return - } - pp := path.Join(ice.VAR_PROXY, m.Option(ice.POD), p) - cache, size := time.Now().Add(-time.Hour*24), int64(0) - if s, e := file.StatFile(pp); e == nil { - cache, size = s.ModTime(), s.Size() - } - if p == ice.BIN_ICE_BIN { - m.Option(ice.MSG_USERROLE, aaa.TECH) - } - m.Cmd(SPACE, m.Option(ice.POD), SPIDE, ice.DEV, SPIDE_RAW, MergeLink(m, SHARE_PROXY), SPIDE_PART, m.OptionSimple(ice.POD), nfs.PATH, p, nfs.SIZE, size, CACHE, cache.Format(ice.MOD_TIME), UPLOAD, "@"+p) - if file.ExistsFile(pp) { - m.RenderDownload(pp) - } else { - m.RenderDownload(p) - } -} 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: @@ -107,14 +76,6 @@ func init() { LOGIN: {Hand: func(m *ice.Message, arg ...string) { m.EchoQRCode(m.Cmd(SHARE, mdb.CREATE, mdb.TYPE, LOGIN).Option(mdb.LINK)).ProcessInner() }}, - SERVE_LOGIN: {Hand: func(m *ice.Message, arg ...string) { - if m.Option(ice.MSG_USERNAME) == "" && m.Option(SHARE) != "" { - switch msg := m.Cmd(SHARE, m.Option(SHARE)); msg.Append(mdb.TYPE) { - case STORM, FIELD: - msg.Table(func(value ice.Maps) { aaa.SessAuth(m, value) }) - } - } - }}, ice.PS: {Hand: func(m *ice.Message, arg ...string) { if m.Warn(len(arg) == 0 || arg[0] == "", ice.ErrNotValid, SHARE) { return @@ -132,7 +93,7 @@ func init() { RenderMain(m) } }}, - }, mdb.HashAction(mdb.FIELD, "time,hash,username,usernick,userrole,river,storm,type,name,text", mdb.EXPIRE, mdb.DAYS), ServeAction(), aaa.WhiteAction()), Hand: func(m *ice.Message, arg ...string) { + }, mdb.HashAction(mdb.FIELD, "time,hash,username,usernick,userrole,river,storm,type,name,text", mdb.EXPIRE, mdb.DAYS), aaa.WhiteAction()), Hand: func(m *ice.Message, arg ...string) { if ctx.PodCmd(m, SHARE, arg) { return } @@ -144,7 +105,7 @@ func init() { } }}, SHARE_CACHE: {Hand: func(m *ice.Message, arg ...string) { _share_cache(m, arg...) }}, - SHARE_LOCAL: {Hand: func(m *ice.Message, arg ...string) { _share_local(m, arg...) }}, + SHARE_LOCAL: {Hand: func(m *ice.Message, arg ...string) { ShareLocalFile(m, arg...) }}, SHARE_LOCAL_AVATAR: {Hand: func(m *ice.Message, arg ...string) { m.RenderDownload(strings.TrimPrefix(m.CmdAppend(aaa.USER, m.Option(ice.MSG_USERNAME), aaa.AVATAR), SHARE_LOCAL)) }}, @@ -158,3 +119,34 @@ func init() { func IsNotValidShare(m *ice.Message, time string) bool { return m.Warn(time < m.Time(), ice.ErrNotValid, m.Option(SHARE), time, m.Time(), logs.FileLineMeta(2)) } +func ShareLocalFile(m *ice.Message, arg ...string) { + p := path.Join(arg...) + switch ls := strings.Split(p, ice.PS); ls[0] { + case ice.ETC, ice.VAR: + if m.Warn(m.Option(ice.MSG_USERROLE) == aaa.VOID, ice.ErrNotRight, p) { + return + } + default: + if m.Option(ice.POD) == "" && !aaa.Right(m, ls) { + return + } + } + if m.Option(ice.POD) == "" { + m.RenderDownload(p) + return + } + pp := path.Join(ice.VAR_PROXY, m.Option(ice.POD), p) + cache, size := time.Now().Add(-time.Hour*24), int64(0) + if s, e := file.StatFile(pp); e == nil { + cache, size = s.ModTime(), s.Size() + } + if p == ice.BIN_ICE_BIN { + m.Option(ice.MSG_USERROLE, aaa.TECH) + } + m.Cmd(SPACE, m.Option(ice.POD), SPIDE, ice.DEV, SPIDE_RAW, MergeLink(m, SHARE_PROXY), SPIDE_PART, m.OptionSimple(ice.POD), nfs.PATH, p, nfs.SIZE, size, CACHE, cache.Format(ice.MOD_TIME), UPLOAD, "@"+p) + if file.ExistsFile(pp) { + m.RenderDownload(pp) + } else { + m.RenderDownload(p) + } +} diff --git a/base/web/space.go b/base/web/space.go index efe3134f..224adc41 100644 --- a/base/web/space.go +++ b/base/web/space.go @@ -21,7 +21,7 @@ import ( func _space_dial(m *ice.Message, dev, name string, arg ...string) { msg := m.Cmd(SPIDE, tcp.CLIENT, dev, PP(SPACE)) - uri := kit.ParseURL(strings.Replace(kit.MergeURL(msg.Append(DOMAIN), mdb.TYPE, ice.Info.NodeType, mdb.NAME, name, arg), ice.HTTP, "ws", 1)) + uri := kit.ParseURL(strings.Replace(kit.MergeURL(msg.Append(DOMAIN), mdb.TYPE, ice.Info.NodeType, mdb.NAME, name, arg), HTTP, "ws", 1)) args := kit.SimpleKV("type,name,host,port", msg.Append(tcp.PROTOCOL), dev, msg.Append(tcp.HOST), msg.Append(tcp.PORT)) prints := false m.Go(func() { @@ -47,6 +47,7 @@ func _space_dial(m *ice.Message, dev, name string, arg ...string) { } func _space_fork(m *ice.Message) { if conn, e := websocket.Upgrade(m.W, m.R, nil, ice.MOD_BUFS, ice.MOD_BUFS); m.Assert(e) { + m.Options(ice.MSG_USERADDR, kit.Select(m.R.RemoteAddr, m.R.Header.Get(ice.MSG_USERADDR))) text := kit.Select(m.Option(ice.MSG_USERADDR), m.Option(mdb.TEXT)) name := strings.ToLower(kit.ReplaceAll(kit.Select(m.Option(ice.MSG_USERADDR), m.Option(mdb.NAME)), ice.PT, "_", ice.DF, "_")) args := kit.Simple(mdb.TYPE, kit.Select(WORKER, m.Option(mdb.TYPE)), mdb.NAME, name, mdb.TEXT, text, m.OptionSimple(SHARE, RIVER, ice.MSG_USERUA, cli.DAEMON)) @@ -175,7 +176,7 @@ func init() { Index.MergeCommands(ice.Commands{ SPACE: {Name: "space name cmds auto", Help: "空间站", Actions: ice.MergeActions(ice.Actions{ tcp.DIAL: {Name: "dial dev=ops name", Hand: func(m *ice.Message, arg ...string) { - if strings.HasPrefix(m.Option(ice.DEV), ice.HTTP) { + if strings.HasPrefix(m.Option(ice.DEV), HTTP) { m.Cmd(SPIDE, mdb.CREATE, ice.DEV, m.Option(ice.DEV)) m.Option(ice.DEV, ice.DEV) } diff --git a/base/web/spide.go b/base/web/spide.go index fb073a53..498afa54 100644 --- a/base/web/spide.go +++ b/base/web/spide.go @@ -259,8 +259,6 @@ const ( OPEN = "open" FULL = "full" LINK = "link" - HTTP = "http" - FORM = "form" MERGE = "merge" ADDRESS = "address" REQUEST = "request" @@ -289,7 +287,7 @@ func init() { tcp.CLIENT: {Hand: func(m *ice.Message, arg ...string) { msg := m.Cmd("", kit.Select(ice.DEV, arg, 0)) ls := kit.Split(msg.Append(kit.Keys(SPIDE_CLIENT, tcp.HOST)), ice.DF) - m.Push(tcp.HOST, ls[0]).Push(tcp.PORT, kit.Select(kit.Select("443", "80", msg.Append(CLIENT_PROTOCOL) == ice.HTTP), ls, 1)) + m.Push(tcp.HOST, ls[0]).Push(tcp.PORT, kit.Select(kit.Select("443", "80", msg.Append(CLIENT_PROTOCOL) == HTTP), ls, 1)) m.Push(DOMAIN, msg.Append(CLIENT_PROTOCOL)+"://"+msg.Append(CLIENT_HOSTNAME)+kit.Select("", arg, 1)) m.Push(tcp.PROTOCOL, msg.Append(CLIENT_PROTOCOL)).Push(tcp.HOSTNAME, msg.Append(CLIENT_HOSTNAME)) }}, diff --git a/conf.go b/conf.go index c26a8f40..c9dd10ad 100644 --- a/conf.go +++ b/conf.go @@ -19,10 +19,11 @@ const ( FAILURE = "failure" PROCESS = "process" - HTTP = "http" - AUTO = "auto" - LIST = "list" - BACK = "back" + HTTPS = "https" + HTTP = "http" + AUTO = "auto" + LIST = "list" + BACK = "back" BASE = "base" CORE = "core" diff --git a/core/chat/pod.go b/core/chat/pod.go index 2b95012a..0aeb5315 100644 --- a/core/chat/pod.go +++ b/core/chat/pod.go @@ -17,7 +17,7 @@ const POD = "pod" func init() { Index.MergeCommands(ice.Commands{ - POD: {Name: "pod", Help: "节点", Actions: ice.MergeActions(ctx.CmdAction(), web.ServeAction(), web.ApiAction(), aaa.WhiteAction()), Hand: func(m *ice.Message, arg ...string) { + POD: {Name: "pod", Help: "节点", Actions: ice.MergeActions(ctx.CmdAction(), web.ApiAction(), aaa.WhiteAction()), Hand: func(m *ice.Message, arg ...string) { if web.OptionAgentIs(m, "curl", "wget") { m.Cmdy(web.SHARE_LOCAL, ice.BIN_ICE_BIN, kit.Dict(ice.POD, kit.Select("", arg, 0), ice.MSG_USERROLE, aaa.TECH)) return diff --git a/core/code/publish.go b/core/code/publish.go index d9d9040b..c94149b3 100644 --- a/core/code/publish.go +++ b/core/code/publish.go @@ -65,6 +65,11 @@ func _publish_contexts(m *ice.Message, arg ...string) { const PUBLISH = "publish" func init() { + web.Index.MergeCommands(ice.Commands{ + web.PP(ice.PUBLISH): {Name: "/publish/", Help: "定制化", Actions: aaa.WhiteAction(), Hand: func(m *ice.Message, arg ...string) { + web.ShareLocalFile(m, ice.USR_PUBLISH, path.Join(arg...)) + }}, + }) Index.MergeCommands(ice.Commands{ PUBLISH: {Name: "publish path auto create volcanos icebergs intshell", Help: "发布", Actions: ice.MergeActions(ice.Actions{ ice.VOLCANOS: {Help: "火山架", Hand: func(m *ice.Message, arg ...string) { diff --git a/core/code/vimer.go b/core/code/vimer.go index cb7de036..0fcfbcc1 100644 --- a/core/code/vimer.go +++ b/core/code/vimer.go @@ -48,6 +48,14 @@ func _vimer_make(m *ice.Message, dir string, msg *ice.Message) { const VIMER = "vimer" func init() { + web.Index.MergeCommands(ice.Commands{ + web.PP(ice.REQUIRE, ice.SRC): {Name: "/require/src/", Help: "源代码", Actions: ice.MergeActions(ctx.CmdAction(), aaa.RoleAction()), Hand: func(m *ice.Message, arg ...string) { + web.ShareLocalFile(m, ice.SRC, path.Join(arg...)) + }}, + web.PP(ice.REQUIRE, ice.USR): {Name: "/require/usr/", Help: "代码库", Hand: func(m *ice.Message, arg ...string) { + web.ShareLocalFile(m, ice.USR, path.Join(arg...)) + }}, + }) Index.MergeCommands(ice.Commands{ VIMER: {Name: "vimer path=src/@key file=main.go line=1 list", Help: "编辑器", Meta: kit.Dict(ctx.STYLE, INNER), Actions: ice.MergeActions(ice.Actions{ mdb.SEARCH: {Hand: func(m *ice.Message, arg ...string) { @@ -180,7 +188,7 @@ func init() { Index.MergeCommands(ice.Commands{TEMPLATE: {Name: "template type name text auto", Help: "模板", Actions: mdb.RenderAction()}}) Index.MergeCommands(ice.Commands{COMPLETE: {Name: "complete type name text auto", Help: "补全", Actions: mdb.RenderAction()}}) Index.MergeCommands(ice.Commands{NAVIGATE: {Name: "navigate type name text auto", Help: "跳转", Actions: mdb.RenderAction()}}) - ice.AddMerges(func(c *ice.Context, key string, cmd *ice.Command, sub string, action *ice.Action) ice.Handler { + ice.AddMergeAction(func(c *ice.Context, key string, cmd *ice.Command, sub string, action *ice.Action) ice.Handler { switch sub { case TEMPLATE, COMPLETE, NAVIGATE: return func(m *ice.Message, arg ...string) { m.Cmd(sub, mdb.CREATE, key, m.PrefixKey()) } diff --git a/core/code/webpack.go b/core/code/webpack.go index 54839e7b..04e2b9a0 100644 --- a/core/code/webpack.go +++ b/core/code/webpack.go @@ -12,14 +12,13 @@ import ( "shylinux.com/x/icebergs/base/ctx" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" - "shylinux.com/x/icebergs/base/web" kit "shylinux.com/x/toolkits" ) func _volcanos(m *ice.Message, p ...string) string { return ice.USR_VOLCANOS + path.Join(p...) } func _publish(m *ice.Message, p ...string) string { return ice.USR_PUBLISH + path.Join(p...) } func _require(m *ice.Message, p string) string { - return path.Join(ice.PS, strings.TrimPrefix(strings.Replace(p, ice.USR_MODULES, web.REQUIRE_MODULES, 1), ice.USR_VOLCANOS)) + return path.Join(ice.PS, strings.TrimPrefix(strings.Replace(p, ice.USR_MODULES, "/require/modules/", 1), ice.USR_VOLCANOS)) } func _webpack_css(m *ice.Message, css, js io.Writer, p string) { fmt.Fprintln(css, kit.Format("/* %s */", _require(m, p))) diff --git a/data.go b/data.go index 754a47ea..f9ac9bb2 100644 --- a/data.go +++ b/data.go @@ -11,11 +11,39 @@ 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() string { return m.Prefix(m.CommandKey()) } +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(strings.ReplaceAll(m.Prefix(m._key, kit.Keys(arg...)), PT, PS)), WEB) + PS } func (m *Message) Prefix(arg ...string) string { return m.Target().Prefix(arg...) } +func (m *Message) Confv(arg ...Any) (val Any) { + run := func(conf *Config) { + if len(arg) == 1 { + val = conf.Value + return + } else if len(arg) > 2 { + if arg[1] == nil || arg[1] == "" { + conf.Value = arg[2] + } else { + kit.Value(conf.Value, arg[1:]...) + } + } + val = kit.Value(conf.Value, arg[1]) + } + key := kit.Format(arg[0]) + kit.If(key == "", func() { key = m._key }) + if conf, ok := m.target.Configs[key]; ok { + run(conf) + } else if conf, ok := m.source.Configs[key]; ok { + run(conf) + } else { + m.Search(key, func(p *Context, s *Context, key string, conf *Config) { run(conf) }) + } + return +} +func (m *Message) Conf(arg ...Any) string { return kit.Format(m.Confv(arg...)) } func SaveImportant(m *Message, arg ...string) { if Info.Important != true { diff --git a/exec.go b/exec.go index b58db7d8..e5f424e0 100644 --- a/exec.go +++ b/exec.go @@ -58,6 +58,12 @@ func (m *Message) Go(cb func(), arg ...Any) { task.Put(arg[0], func(task *task.Task) { m.TryCatch(m, true, func(m *Message) { cb() }) }) } +func (m *Message) Cmd(arg ...Any) *Message { return m._command(arg...) } +func (m *Message) Cmdy(arg ...Any) *Message { return m.Copy(m._command(arg...)) } +func (m *Message) Cmdx(arg ...Any) string { + res := kit.Select("", m._command(arg...).meta[MSG_RESULT], 0) + return kit.Select("", res, res != ErrWarn) +} func (m *Message) CmdHand(cmd *Command, key string, arg ...string) *Message { if m._cmd, m._key = cmd, key; cmd == nil { return m diff --git a/info.go b/info.go index 584a4701..344b5bd1 100644 --- a/info.go +++ b/info.go @@ -57,7 +57,7 @@ var Info = struct { Log: func(m *Message, p, l, s string) {}, } -func AddMerges(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 { diff --git a/meta.go b/meta.go index e200953e..385dcadd 100644 --- a/meta.go +++ b/meta.go @@ -95,8 +95,8 @@ func (m *Message) Push(key string, value Any, arg ...Any) *Message { kit.If(len(head) == 0 && !m.FieldsIsDetail(), func() { head = kit.Split(m.OptionFields()) }) switch value := value.(type) { case Map: - kit.If(len(head) == 0, func() { head = kit.SortedKey(kit.KeyValue(nil, "", value)) }) var val Map + kit.If(len(head) == 0, func() { head = kit.SortedKey(kit.KeyValue(nil, "", value)) }) kit.If(len(arg) > 1, func() { val, _ = arg[1].(Map) }) kit.For(head, func(k string) { var v Any @@ -341,9 +341,7 @@ func (m *Message) SortStrR(key string) *Message { return m.Sort(key, STR_R) } func (m *Message) SortIntR(key string) *Message { return m.Sort(key, INT_R) } func (m *Message) SortInt(key string) *Message { return m.Sort(key, INT) } -func (m *Message) Detail(arg ...Any) string { - return kit.Select("", m.meta[MSG_DETAIL], 0) -} +func (m *Message) Detail(arg ...Any) string { return kit.Select("", m.meta[MSG_DETAIL], 0) } func (m *Message) Detailv(arg ...Any) []string { kit.If(len(arg) > 0, func() { m.meta[MSG_DETAIL] = kit.Simple(arg...) }) return m.meta[MSG_DETAIL] diff --git a/misc.go b/misc.go index c0bcb44c..1c80a4be 100644 --- a/misc.go +++ b/misc.go @@ -67,9 +67,7 @@ func (m *Message) SetAppend(arg ...string) *Message { kit.If(len(arg) == 0, func() { m.OptionFields("") }) return m.Set(MSG_APPEND, arg...) } -func (m *Message) SetResult(arg ...string) *Message { - return m.Set(MSG_RESULT, arg...) -} +func (m *Message) SetResult(arg ...string) *Message { return m.Set(MSG_RESULT, arg...) } func (m *Message) PushRecord(value Any, arg ...string) *Message { return m.Push("", value, kit.Split(kit.Join(arg))) } diff --git a/misc/bash/sess.go b/misc/bash/sess.go index 2b24c2d6..acbe74b7 100644 --- a/misc/bash/sess.go +++ b/misc/bash/sess.go @@ -22,7 +22,7 @@ const SESS = "sess" func init() { Index.MergeCommands(ice.Commands{ - web.WEB_LOGIN: {Hand: func(m *ice.Message, arg ...string) { + "_login": {Hand: func(m *ice.Message, arg ...string) { if f, _, e := m.R.FormFile(SUB); e == nil { defer f.Close() if b, e := ioutil.ReadAll(f); e == nil { diff --git a/misc/git/repos.go b/misc/git/repos.go index 1805857d..88e03163 100644 --- a/misc/git/repos.go +++ b/misc/git/repos.go @@ -201,6 +201,29 @@ const ( const REPOS = "repos" func init() { + web.Index.MergeCommands(ice.Commands{ + web.PP(ice.REQUIRE): {Name: "/require/shylinux.com/x/volcanos/proto.js", Help: "代码库", Hand: func(m *ice.Message, arg ...string) { + if len(arg) < 4 { + m.RenderStatusBadRequest() + return + } else if path.Join(arg[:3]...) == ice.Info.Make.Module && nfs.ExistsFile(m, path.Join(arg[3:]...)) { + m.RenderDownload(path.Join(arg[3:]...)) + return + } + p := path.Join(kit.Select(ice.USR_REQUIRE, m.Cmdx(cli.SYSTEM, "go", "env", "GOMODCACHE")), path.Join(arg...)) + if !nfs.ExistsFile(m, p) { + if p = path.Join(ice.USR_REQUIRE, path.Join(arg...)); !nfs.ExistsFile(m, p) { + ls := strings.SplitN(path.Join(arg[:3]...), ice.AT, 2) + if v := kit.Select(ice.Info.Gomod[ls[0]], ls, 1); v == "" { + m.Cmd(cli.SYSTEM, "git", "clone", "https://"+ls[0], path.Join(ice.USR_REQUIRE, path.Join(arg[:3]...))) + } else { + m.Cmd(cli.SYSTEM, "git", "clone", "-b", v, "https://"+ls[0], path.Join(ice.USR_REQUIRE, path.Join(arg[:3]...))) + } + } + } + m.RenderDownload(p) + }}, + }) Index.MergeCommands(ice.Commands{ REPOS: {Name: "repos repos@key branch@key commit@key path@key auto", Help: "代码库", Actions: ice.MergeActions(ice.Actions{ ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { diff --git a/misc/lark/msg.go b/misc/lark/msg.go index 0c62800f..36069bd8 100644 --- a/misc/lark/msg.go +++ b/misc/lark/msg.go @@ -60,7 +60,7 @@ const MSG = "msg" func init() { Index.MergeCommands(ice.Commands{ - web.WEB_LOGIN: {Hand: func(m *ice.Message, arg ...string) { + "_login": {Hand: func(m *ice.Message, arg ...string) { m.Option(ice.MSG_USERZONE, LARK) }}, "/msg": {Name: "/msg", Help: "聊天消息", Hand: func(m *ice.Message, arg ...string) { @@ -83,7 +83,7 @@ func init() { }}, MSG: {Name: "msg", Help: "聊天消息", Actions: ice.Actions{ "location": {Hand: func(m *ice.Message, arg ...string) {}}, - "image": {Hand: func(m *ice.Message, arg ...string) {}}, + "image": {Hand: func(m *ice.Message, arg ...string) {}}, "card": {Hand: func(m *ice.Message, arg ...string) { kit.For(kit.Value(m.Optionv(ice.MSG_USERDATA), "action.value"), func(k string, v string) { m.Option(k, v) }) m.Cmdy(TALK, kit.Parse(nil, "", kit.Split(m.Option(ice.CMD))...)) diff --git a/misc/node/npm.go b/misc/node/npm.go index 640f148c..662c478f 100644 --- a/misc/node/npm.go +++ b/misc/node/npm.go @@ -1,14 +1,27 @@ package node -import "shylinux.com/x/ice" +import ( + "path" + + "shylinux.com/x/ice" + "shylinux.com/x/icebergs/base/cli" + "shylinux.com/x/icebergs/base/nfs" + kit "shylinux.com/x/toolkits" +) type npm struct { ice.Code - list string `name:"list auto" help:"打包构建"` + require string `name:"require" http:"/require/modules/"` + list string `name:"list auto"` } +func (s npm) Require(m *ice.Message, arg ...string) { + p := path.Join(ice.USR_MODULES, path.Join(arg...)) + kit.If(!nfs.ExistsFile(m, p), func() { m.Cmd(cli.SYSTEM, "npm", "install", arg[0], kit.Dict(cli.CMD_DIR, ice.USR)) }) + m.RenderDownload(p) +} func (s npm) List(m *ice.Message) { - + m.Cmdy(nfs.DIR, ice.USR_MODULES) } func init() { ice.CodeCtxCmd(npm{}) } diff --git a/misc/vim/sess.go b/misc/vim/sess.go index e4c0dc0b..b34c1a2d 100644 --- a/misc/vim/sess.go +++ b/misc/vim/sess.go @@ -2,7 +2,6 @@ package vim import ( ice "shylinux.com/x/icebergs" - "shylinux.com/x/icebergs/base/web" ) const ( @@ -18,5 +17,5 @@ const ( const SESS = "sess" func init() { - Index.MergeCommands(ice.Commands{web.WEB_LOGIN: {Hand: func(m *ice.Message, arg ...string) { m.Cmdy("web.code.bash._login", arg) }}}) + Index.MergeCommands(ice.Commands{"_login": {Hand: func(m *ice.Message, arg ...string) { m.Cmdy("web.code.bash._login", arg) }}}) } diff --git a/option.go b/option.go index d378fb1a..905e2f80 100644 --- a/option.go +++ b/option.go @@ -75,42 +75,25 @@ func (m *Message) StatusTimeCountTotal(arg ...Any) *Message { return m.Status(TIME, m.Time(), kit.MDB_COUNT, kit.Split(m.FormatSize())[0], kit.MDB_TOTAL, arg, kit.MDB_COST, m.FormatCost()) } -func (m *Message) Process(cmd string, arg ...Any) { - m.Options(MSG_PROCESS, cmd).Option(PROCESS_ARG, arg...) -} -func (m *Message) ProcessLocation(arg ...Any) { - m.Process(PROCESS_LOCATION, arg...) +func (m *Message) Process(cmd string, arg ...Any) *Message { + return m.Options(MSG_PROCESS, cmd, PROCESS_ARG, kit.Simple(arg...)) } +func (m *Message) ProcessLocation(arg ...Any) { m.Process(PROCESS_LOCATION, arg...) } func (m *Message) ProcessReplace(url string, arg ...Any) { m.Process(PROCESS_REPLACE, kit.MergeURL(url, arg...)) } -func (m *Message) ProcessHistory(arg ...Any) { - m.Process(PROCESS_HISTORY, arg...) -} -func (m *Message) ProcessConfirm(arg ...Any) { - m.Process(PROCESS_CONFIRM, arg...) -} +func (m *Message) ProcessHistory(arg ...Any) { m.Process(PROCESS_HISTORY, arg...) } +func (m *Message) ProcessConfirm(arg ...Any) { m.Process(PROCESS_CONFIRM, arg...) } func (m *Message) ProcessRefresh(arg ...string) { - m.Process(PROCESS_REFRESH) - if d, e := time.ParseDuration(kit.Select("30ms", arg, 0)); e == nil { - m.Option(PROCESS_ARG, int(d/time.Millisecond)) - } + m.Process(PROCESS_REFRESH).Option(PROCESS_ARG, int(kit.Duration(kit.Select("30ms", arg, 0))/time.Millisecond)) } -func (m *Message) ProcessRewrite(arg ...Any) { - m.Process(PROCESS_REWRITE, arg...) -} -func (m *Message) ProcessDisplay(arg ...Any) { - m.Process(PROCESS_DISPLAY) - m.Option(MSG_DISPLAY, arg...) -} -func (m *Message) ProcessField(arg ...Any) { - m.Process(PROCESS_FIELD) - m.Option(FIELD_PREFIX, arg...) -} -func (m *Message) ProcessInner() { m.Process(PROCESS_INNER) } -func (m *Message) ProcessAgain() { m.Process(PROCESS_AGAIN) } -func (m *Message) ProcessHold(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) { m.Process(PROCESS_OPEN, url) } +func (m *Message) ProcessRewrite(arg ...Any) { m.Process(PROCESS_REWRITE, arg...) } +func (m *Message) ProcessDisplay(arg ...Any) { m.Process(PROCESS_DISPLAY).Option(MSG_DISPLAY, arg...) } +func (m *Message) ProcessField(arg ...Any) { m.Process(PROCESS_FIELD).Option(FIELD_PREFIX, arg...) } +func (m *Message) ProcessInner() { m.Process(PROCESS_INNER) } +func (m *Message) ProcessAgain() { m.Process(PROCESS_AGAIN) } +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) { m.Process(PROCESS_OPEN, url) } diff --git a/type.go b/type.go index ffad0366..16b1a865 100644 --- a/type.go +++ b/type.go @@ -255,7 +255,7 @@ func (m *Message) Spawn(arg ...Any) *Message { case Maps: kit.For(val, func(k, v string) { msg.Option(k, v) }) case Map: - kit.For(val, func(k string, v Any) { msg.Option(k, v) }) + kit.For(kit.KeyValue(nil, "", val), func(k string, v Any) { msg.Option(k, v) }) case *Context: msg.target = val case *Command: @@ -389,36 +389,3 @@ func (m *Message) Actions(key string) *Action { func (m *Message) Commands(key string) *Command { return m.Target().Commands[key] } - -func (m *Message) Cmd(arg ...Any) *Message { return m._command(arg...) } -func (m *Message) Cmdy(arg ...Any) *Message { return m.Copy(m._command(arg...)) } -func (m *Message) Cmdx(arg ...Any) string { - res := kit.Select("", m._command(arg...).meta[MSG_RESULT], 0) - return kit.Select("", res, res != ErrWarn) -} -func (m *Message) Confv(arg ...Any) (val Any) { - run := func(conf *Config) { - if len(arg) == 1 { - val = conf.Value - return - } else if len(arg) > 2 { - if arg[1] == nil || arg[1] == "" { - conf.Value = arg[2] - } else { - kit.Value(conf.Value, arg[1:]...) - } - } - val = kit.Value(conf.Value, arg[1]) - } - key := kit.Format(arg[0]) - kit.If(key == "", func() { key = m._key }) - if conf, ok := m.target.Configs[key]; ok { - run(conf) - } else if conf, ok := m.source.Configs[key]; ok { - run(conf) - } else { - m.Search(key, func(p *Context, s *Context, key string, conf *Config) { run(conf) }) - } - return -} -func (m *Message) Conf(arg ...Any) string { return kit.Format(m.Confv(arg...)) }