From 6ccffa64bc8465b9df47a2b9d273fa858acec72f Mon Sep 17 00:00:00 2001 From: shylinux Date: Wed, 26 Apr 2023 23:36:53 +0800 Subject: [PATCH] opt service --- base/cli/system.go | 2 +- base/log/debug.go | 9 ++++++--- base/nfs/dir.go | 14 ++++++++------ base/nfs/trash.go | 2 +- base/web/cache.go | 11 ++++++----- base/web/dream.go | 14 +++++--------- base/web/option.go | 7 +++++++ base/web/serve.go | 11 +++++++---- base/web/space.go | 9 ++++++++- base/web/token.go | 11 +++++++++-- conf.go | 1 + core/code/code.go | 1 + core/code/compile.go | 11 ++++------- core/code/publish.go | 22 +++++++--------------- core/code/vimer.go | 5 ++++- core/code/xterm.go | 6 +++--- misc/git/repos.go | 36 +++++++++++++++++++++-------------- misc/git/service.go | 22 ++++++++++++++++------ misc/git/status.go | 7 ++++--- misc/git/token.go | 45 ++++++++++---------------------------------- misc/git/total.go | 1 - option.go | 6 ++++++ 22 files changed, 136 insertions(+), 117 deletions(-) diff --git a/base/cli/system.go b/base/cli/system.go index 6378e8a1..3ec4f543 100644 --- a/base/cli/system.go +++ b/base/cli/system.go @@ -31,7 +31,7 @@ func _system_cmd(m *ice.Message, arg ...string) *exec.Cmd { } } }) - if bin == "" { + if bin == "" && nfs.Exists(m, ice.ETC_PATH) { if text := m.Cmdx(nfs.CAT, ice.ETC_PATH); len(text) > 0 { if bin = _system_find(m, arg[0], strings.Split(text, lex.NL)...); bin != "" { m.Logs(FIND, "etcpath cmd", bin) diff --git a/base/log/debug.go b/base/log/debug.go index b370426a..eb5e0763 100644 --- a/base/log/debug.go +++ b/base/log/debug.go @@ -18,6 +18,9 @@ const DEBUG = "debug" func _debug_file(k string) string { return ice.VAR_LOG + k + ".log" } func init() { + const ( + LEVEL = "level" + ) Index.MergeCommands(ice.Commands{ DEBUG: {Name: "debug level=error,bench,debug,error,watch offset limit filter auto reset doc", Help: "后台日志", Actions: ice.Actions{ "doc": {Help: "文档", Hand: func(m *ice.Message, arg ...string) { m.ProcessOpen("https://pkg.go.dev/std") }}, @@ -36,7 +39,7 @@ func init() { if _, e := time.Parse(kit.Split(ice.MOD_TIMES)[0], ls[0]); e != nil || len(ls) < 6 { m.Push(mdb.TIME, "").Push(mdb.ID, "") m.Push(nfs.PATH, "").Push(nfs.FILE, "").Push(nfs.LINE, "") - m.Push(ctx.SHIP, "").Push(ctx.ACTION, "").Push(nfs.CONTENT, line) + m.Push(ctx.SHIP, "").Push(LEVEL, "").Push(nfs.CONTENT, line) return } m.Push(mdb.TIME, ls[0]+lex.SP+ls[1]).Push(mdb.ID, ls[2]) @@ -59,7 +62,7 @@ func init() { ls[4], ls[5] = ls[4]+lex.SP+_ls[0], _ls[1] } } - m.Push(ctx.SHIP, ls[3]).Push(ctx.ACTION, ls[4]).Push(nfs.CONTENT, ls[5]) + m.Push(ctx.SHIP, ls[3]).Push(LEVEL, ls[4]).Push(nfs.CONTENT, ls[5]) stats[ls[4]]++ }) case WATCH: @@ -73,7 +76,7 @@ func init() { m.Push(nfs.PATH, ice.USR_ICEBERGS) m.Push(nfs.FILE, strings.TrimSpace(strings.Split(ls[5][i:], nfs.DF)[0])) m.Push(nfs.LINE, strings.TrimSpace(strings.Split(ls[5][i:], nfs.DF)[1])) - m.Push(ctx.SHIP, ls[3]).Push(ctx.ACTION, ls[4]).Push(nfs.CONTENT, ls[5][:i]) + m.Push(ctx.SHIP, ls[3]).Push(LEVEL, ls[4]).Push(nfs.CONTENT, ls[5][:i]) stats[ls[4]]++ }) } diff --git a/base/nfs/dir.go b/base/nfs/dir.go index be6837b1..e7032252 100644 --- a/base/nfs/dir.go +++ b/base/nfs/dir.go @@ -36,8 +36,8 @@ func _dir_list(m *ice.Message, root string, dir string, level int, deep bool, di } p, pp := path.Join(root, dir, s.Name()), path.Join(dir, s.Name()) isDir := s.IsDir() || kit.IsDir(p) && deep == false - isBin := s.Mode().String()[3] == 'x' - if !(dir_type == TYPE_BIN && !isBin || dir_type == TYPE_CAT && isDir || dir_type == TYPE_DIR && !isDir) && (dir_reg == nil || dir_reg.MatchString(s.Name())) { + isBin := s.Mode().String()[3] == 'x' || kit.Ext(s.Name()) == "exe" + if !(dir_type == TYPE_BIN && (!isBin || isDir) || dir_type == TYPE_CAT && isDir || dir_type == TYPE_DIR && !isDir) && (dir_reg == nil || dir_reg.MatchString(s.Name())) { switch cb := m.OptionCB("").(type) { case func(os.FileInfo, string): cb(s, p) @@ -90,10 +90,12 @@ func _dir_list(m *ice.Message, root string, dir string, level int, deep bool, di } m.Push(mdb.HASH, kit.Select(h[:6], h[:], field == mdb.HASH)) case mdb.LINK: - if strings.Contains(p, "ice.windows.") { + if isDir { + m.Push(mdb.LINK, "") + } else if strings.Contains(p, "ice.windows.") { m.PushDownload(mdb.LINK, "ice.exe", p) } else { - m.PushDownload(mdb.LINK, kit.Select("", s.Name(), !isDir), p) + m.PushDownload(mdb.LINK, p) } case mdb.SHOW: switch p := kit.MergeURL("/share/local/"+p, ice.POD, m.Option(ice.MSG_USERPOD)); kit.Ext(s.Name()) { @@ -142,8 +144,8 @@ const ( DIR_DEEP = "dir_deep" DIR_REG = "dir_reg" - DIR_DEF_FIELDS = "time,size,path,action" - DIR_WEB_FIELDS = "time,size,path,link,action" + DIR_DEF_FIELDS = "time,path,size,action" + DIR_WEB_FIELDS = "time,path,size,link,action" DIR_CLI_FIELDS = "path,size,time" ROOT = "root" diff --git a/base/nfs/trash.go b/base/nfs/trash.go index ef711acb..1b66bc2c 100644 --- a/base/nfs/trash.go +++ b/base/nfs/trash.go @@ -22,7 +22,7 @@ func _trash_create(m *ice.Message, from string) { p := path.Join(ice.VAR_TRASH, path.Base(from)) kit.If(!s.IsDir(), func() { Open(m, from, func(r io.Reader) { p = path.Join(ice.VAR_TRASH, kit.HashsPath(r)) }) }) RemoveAll(m, p) - kit.If(!m.Warn(Rename(m, from, p)), func() { mdb.HashCreate(m, FROM, from, FILE, p) }) + kit.If(!m.Warn(Rename(m, from, p)), func() { mdb.HashCreate(m, FROM, kit.Paths(from), FILE, p) }) } const TRASH = "trash" diff --git a/base/web/cache.go b/base/web/cache.go index f5aead2b..89323ae9 100644 --- a/base/web/cache.go +++ b/base/web/cache.go @@ -72,6 +72,11 @@ func _cache_upload(m *ice.Message, r *http.Request) (mime, name, file, size stri } func _cache_download(m *ice.Message, r *http.Response, file string, cb ice.Any) string { if f, p, e := miss.CreateFile(file); !m.Warn(e, ice.ErrNotValid, DOWNLOAD) { + defer func() { + if s, e := os.Stat(file); e == nil && s.Size() == 0 { + nfs.Remove(m, file) + } + }() defer f.Close() last, base := 0, 10 nfs.CopyStream(m, f, r.Body, base*ice.MOD_BUFS, kit.Int(kit.Select("100", r.Header.Get(ContentLength))), func(count, total, value int) { @@ -132,11 +137,7 @@ func init() { }}, nfs.PS: {Hand: func(m *ice.Message, arg ...string) { mdb.HashSelectDetail(m, arg[0], func(value ice.Map) { - if kit.Format(value[nfs.FILE]) == "" { - m.RenderResult(value[mdb.TEXT]) - } else { - m.RenderDownload(value[nfs.FILE]) - } + kit.If(kit.Format(value[nfs.FILE]), func() { m.RenderDownload(value[nfs.FILE]) }, func() { m.RenderResult(value[mdb.TEXT]) }) }) }}, }, mdb.HashAction(mdb.SHORT, mdb.TEXT, mdb.FIELD, "time,hash,size,type,name,text,file", ctx.ACTION, WATCH), ice.RenderAction(ice.RENDER_DOWNLOAD)), Hand: func(m *ice.Message, arg ...string) { diff --git a/base/web/dream.go b/base/web/dream.go index bfeeab4e..93b1dae1 100644 --- a/base/web/dream.go +++ b/base/web/dream.go @@ -36,7 +36,7 @@ func _dream_list(m *ice.Message) *ice.Message { }) return m.Sort("status,type,name", ice.STR, ice.STR, ice.STR_R).StatusTimeCount(cli.START, len(list)) } -func _dream_show(m *ice.Message, name string) { +func _dream_start(m *ice.Message, name string) { if m.Warn(name == "", ice.ErrNotValid, mdb.NAME) { return } @@ -123,19 +123,15 @@ func init() { }}, mdb.CREATE: {Name: "create name*=hi repos binary template", Hand: func(m *ice.Message, arg ...string) { m.Option(nfs.REPOS, kit.Select("", kit.Slice(kit.Split(m.Option(nfs.REPOS)), -1), 0)) - _dream_show(m, m.OptionDefault(mdb.NAME, path.Base(m.Option(nfs.REPOS)))) - }}, - cli.START: {Hand: func(m *ice.Message, arg ...string) { - _dream_show(m, m.Option(mdb.NAME)) + _dream_start(m, m.OptionDefault(mdb.NAME, path.Base(m.Option(nfs.REPOS)))) }}, + cli.START: {Hand: func(m *ice.Message, arg ...string) { _dream_start(m, m.Option(mdb.NAME)) }}, cli.STOP: {Hand: func(m *ice.Message, arg ...string) { m.Cmd(SPACE, mdb.MODIFY, m.OptionSimple(mdb.NAME), mdb.STATUS, cli.STOP) m.Go(func() { m.Cmd(SPACE, m.Option(mdb.NAME), ice.EXIT) }) m.Sleep30ms() }}, - nfs.TRASH: {Hand: func(m *ice.Message, arg ...string) { - nfs.Trash(m, path.Join(ice.USR_LOCAL_WORK, m.Option(mdb.NAME))) - }}, + nfs.TRASH: {Hand: func(m *ice.Message, arg ...string) { 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.Sleep30ms(DREAM, cli.START, m.OptionSimple(mdb.NAME)) }) @@ -144,7 +140,7 @@ func init() { DREAM_TABLES: {Hand: func(m *ice.Message, arg ...string) { kit.Switch(m.Option(mdb.TYPE), []string{SERVER, WORKER}, func() { m.PushButton(OPEN) }) }}, - OPEN: {Hand: func(m *ice.Message, arg ...string) { ctx.ProcessOpen(m, m.MergePod(m.Option(mdb.NAME), arg)) }}, + OPEN: {Hand: func(m *ice.Message, arg ...string) { ctx.ProcessOpen(m, m.MergePod(m.Option(mdb.NAME))) }}, }, ctx.CmdAction(), DreamAction()), Hand: func(m *ice.Message, arg ...string) { if len(arg) == 0 { _dream_list(m) diff --git a/base/web/option.go b/base/web/option.go index 78f4139e..35dc05f5 100644 --- a/base/web/option.go +++ b/base/web/option.go @@ -64,6 +64,13 @@ func PushPodCmd(m *ice.Message, cmd string, arg ...string) { }) }) } +func PushImages(m *ice.Message, name string) { + if kit.ExtIsImage(name) { + m.PushImages(IMAGE, name) + } else if kit.ExtIsVideo(name) { + m.PushVideos(VIDEO, name) + } +} func PushNotice(m *ice.Message, arg ...ice.Any) { if m.Option(ice.MSG_DAEMON) == "" { return diff --git a/base/web/serve.go b/base/web/serve.go index 2bf8a536..c742e007 100644 --- a/base/web/serve.go +++ b/base/web/serve.go @@ -183,13 +183,16 @@ func init() { 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)) - c.Commands[sub] = &ice.Command{Name: kit.Select(cmd.Name, action.Name), Actions: ctx.CmdAction(), Hand: action.Hand} + c.Commands[sub] = &ice.Command{Name: kit.Select(cmd.Name, action.Name), Actions: ctx.CmdAction(), Hand: func(m *ice.Message, arg ...string) { + msg := m.Spawn(c, key, cmd) + defer m.Copy(msg) + action.Hand(msg, arg...) + }} } }) } -func Domain(host, port string) string { - return kit.Format("%s://%s:%s", HTTP, host, port) -} +func Domain(host, port string) string { return kit.Format("%s://%s:%s", HTTP, host, port) } func Script(m *ice.Message, str string, arg ...ice.Any) string { return ice.Render(m, ice.RENDER_SCRIPT, kit.Format(str, arg...)) } +func ChatCmdPath(arg ...string) string { return path.Join("/chat/cmd/", path.Join(arg...)) } diff --git a/base/web/space.go b/base/web/space.go index 5114a6c5..95df8d4b 100644 --- a/base/web/space.go +++ b/base/web/space.go @@ -212,7 +212,14 @@ func init() { nfs.PS: {Hand: func(m *ice.Message, arg ...string) { _space_fork(m) }}, }, mdb.HashAction(mdb.SHORT, mdb.NAME, mdb.FIELD, "time,type,name,text", ctx.ACTION, OPEN, REDIAL, kit.Dict("a", 3000, "b", 1000, "c", 1000)), mdb.ClearOnExitHashAction()), Hand: func(m *ice.Message, arg ...string) { if len(arg) < 2 { - mdb.HashSelect(m, arg...).Sort("").Table(func(value ice.Maps) { m.PushButton(kit.Select(OPEN, LOGIN, value[mdb.TYPE] == LOGIN), mdb.REMOVE) }) + mdb.HashSelect(m, arg...).Sort("").Table(func(value ice.Maps) { + if kit.IsIn(value[mdb.TYPE], SERVER, WORKER) { + m.Push(mdb.LINK, tcp.PublishLocalhost(m, m.MergePod(value[mdb.NAME]))) + } else { + m.Push(mdb.LINK, "") + } + m.PushButton(kit.Select(OPEN, LOGIN, value[mdb.TYPE] == LOGIN), mdb.REMOVE) + }) } else { _space_send(m, arg[0], kit.Simple(kit.Split(arg[1]), arg[2:])...) } diff --git a/base/web/token.go b/base/web/token.go index 10a0de39..909a91df 100644 --- a/base/web/token.go +++ b/base/web/token.go @@ -10,9 +10,16 @@ const TOKEN = "token" func init() { Index.MergeCommands(ice.Commands{ - TOKEN: {Name: "token hash auto create prunes", Help: "令牌", Actions: ice.MergeActions(mdb.HashAction(mdb.EXPIRE, mdb.MONTH, mdb.SHORT, mdb.UNIQ, mdb.FIELD, "time,hash,type,name,text")), Hand: func(m *ice.Message, arg ...string) { + TOKEN: {Name: "token hash auto create prunes", Help: "令牌", Actions: ice.MergeActions(ice.Actions{ + mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) { + switch mdb.HashInputs(m, arg); arg[0] { + case mdb.TYPE: + m.Push(arg[0], SERVER, WORKER) + } + }}, + }, 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 { - m.Cmdy("web.code.publish", ice.CONTEXTS, kit.Dict(TOKEN, arg[0])) + m.Cmdy("web.code.publish", "contexts", kit.Dict(TOKEN, arg[0])) } }}, }) diff --git a/conf.go b/conf.go index ca903638..622058fb 100644 --- a/conf.go +++ b/conf.go @@ -254,6 +254,7 @@ const ( // PROCESS PROCESS_RICH = "_rich" PROCESS_GROW = "_grow" PROCESS_OPEN = "_open" + PROCESS_CLOSE = "_close" PROCESS_ARG = "_arg" FIELD_PREFIX = "_prefix" diff --git a/core/code/code.go b/core/code/code.go index badb7f35..28b81aa2 100644 --- a/core/code/code.go +++ b/core/code/code.go @@ -16,6 +16,7 @@ func init() { INSTALL, UPGRADE, WEBPACK, BINPACK, AUTOGEN, COMPILE, PUBLISH, VIMER, INNER, XTERM, PPROF, BENCH, C, SH, SHY, PY, GO, JS, CSS, HTML, + TEMPLATE, COMPLETE, NAVIGATE, ) } func init() { diff --git a/core/code/compile.go b/core/code/compile.go index d0445b18..975e45a7 100644 --- a/core/code/compile.go +++ b/core/code/compile.go @@ -40,7 +40,7 @@ func init() { VERSION = "version" ) Index.MergeCommands(ice.Commands{ - COMPILE: {Name: "compile arch=amd64,386,arm,arm64,mipsle os=linux,darwin,windows src=src/main.go@key run binpack webpack devpack upgrade install", Help: "编译", Actions: ice.MergeActions(ice.Actions{ + COMPILE: {Name: "compile arch=amd64,386,arm,arm64,mipsle os=linux,darwin,windows src=src/main.go@key run binpack webpack devpack install", Help: "编译", Actions: ice.MergeActions(ice.Actions{ ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { cli.IsAlpine(m, GO, "go git") }}, mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) { switch arg[0] { @@ -55,7 +55,6 @@ func init() { BINPACK: {Help: "版本", Hand: func(m *ice.Message, arg ...string) { m.Cmdy(AUTOGEN, BINPACK) }}, WEBPACK: {Help: "打包", Hand: func(m *ice.Message, arg ...string) { m.Cmdy(AUTOGEN, WEBPACK) }}, DEVPACK: {Help: "开发", Hand: func(m *ice.Message, arg ...string) { m.Cmdy(AUTOGEN, DEVPACK) }}, - UPGRADE: {Help: "升级", Hand: func(m *ice.Message, arg ...string) { m.Cmdy(UPGRADE, nfs.TARGET) }}, INSTALL: {Name: "install service*='https://golang.google.cn/dl/' version*=1.15.5", Help: "安装", Hand: func(m *ice.Message, arg ...string) { m.Cmdy(INSTALL, web.DOWNLOAD, kit.Format("%s/go%s.%s-%s.%s", m.Option(SERVICE), m.Option(VERSION), runtime.GOOS, runtime.GOARCH, kit.Select("tar.gz", "zip", runtime.GOOS == cli.WINDOWS)), ice.USR_LOCAL) }}, @@ -64,8 +63,7 @@ func init() { main, file, goos, arch := _compile_target(m, arg...) env := kit.Simple(cli.PATH, cli.BinPath(), cli.HOME, kit.Select(kit.Path(""), kit.Env(cli.HOME)), mdb.Configv(m, cli.ENV), m.Optionv(cli.ENV), cli.GOOS, goos, cli.GOARCH, arch) kit.If(runtime.GOOS == cli.WINDOWS, func() { env = append(env, "GOPATH", kit.HomePath(GO), "GOCACHE", kit.HomePath("go/go-build")) }) - m.Optionv(cli.CMD_ENV, env) - m.Cmd(AUTOGEN, VERSION) + m.Options(cli.CMD_ENV, env).Cmd(AUTOGEN, VERSION) defer m.StatusTime(VERSION, strings.TrimPrefix(m.Cmdx(cli.SYSTEM, GO, VERSION), "go version")) kit.If(!strings.Contains(m.Cmdx(nfs.CAT, ice.GO_MOD), "shylinux.com/x/ice"), func() { m.Cmd(cli.SYSTEM, GO, "get", "shylinux.com/x/ice") }) if msg := m.Cmd(cli.SYSTEM, GO, cli.BUILD, "-o", file, main, ice.SRC_VERSION_GO, ice.SRC_BINPACK_GO); !cli.IsSuccess(msg) { @@ -73,9 +71,8 @@ func init() { return } m.Logs(nfs.SAVE, nfs.TARGET, file, nfs.SOURCE, main) - if m.Cmdy(nfs.DIR, file, "time,size,path,hash,link"); strings.Contains(file, ice.ICE) { - m.Cmdy(PUBLISH, ice.CONTEXTS) - } + m.Cmdy(nfs.DIR, file, "time,path,size,hash,link") + kit.If(strings.Contains(file, ice.ICE), func() { m.Cmdy(PUBLISH, ice.CONTEXTS) }) }}, }) } diff --git a/core/code/publish.go b/core/code/publish.go index bb2b8208..2c96b68f 100644 --- a/core/code/publish.go +++ b/core/code/publish.go @@ -19,16 +19,7 @@ import ( func _publish_bin_list(m *ice.Message) *ice.Message { defer m.SortStrR(mdb.TIME) - m.Option(cli.CMD_DIR, ice.USR_PUBLISH) - for _, ls := range strings.Split(cli.SystemCmds(m, "ls |xargs file |grep executable"), lex.NL) { - if file := strings.TrimSpace(strings.Split(ls, nfs.DF)[0]); file != "" { - if s, e := nfs.StatFile(m, path.Join(ice.USR_PUBLISH, file)); e == nil { - m.Push(mdb.TIME, s.ModTime()).Push(nfs.SIZE, kit.FmtSize(s.Size())).Push(nfs.PATH, file) - m.PushDownload(mdb.LINK, file, path.Join(ice.USR_PUBLISH, file)).PushButton(nfs.TRASH) - } - } - } - return m + return m.Cmdy(nfs.DIR, nfs.PWD, nfs.DIR_WEB_FIELDS, kit.Dict(nfs.DIR_TYPE, nfs.TYPE_BIN, nfs.DIR_DEEP, ice.TRUE, nfs.DIR_ROOT, ice.USR_PUBLISH)) } func _publish_list(m *ice.Message, arg ...string) *ice.Message { defer m.SortStrR(mdb.TIME) @@ -74,13 +65,13 @@ func init() { 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) { - _publish_list(m, kit.ExtReg(HTML, CSS, JS)).Cmdy("", ice.CONTEXTS, ice.MISC).Echo(lex.NL).EchoQRCode(m.Option(ice.MSG_USERWEB)) + _publish_list(m, kit.ExtReg(HTML, CSS, JS)).EchoQRCode(m.Option(ice.MSG_USERWEB)) }}, ice.ICEBERGS: {Help: "冰山架", Hand: func(m *ice.Message, arg ...string) { - _publish_bin_list(m).Cmdy("", ice.CONTEXTS, ice.CORE) + _publish_bin_list(m).Cmdy("", ice.CONTEXTS) }}, ice.INTSHELL: {Help: "神农架", Hand: func(m *ice.Message, arg ...string) { - _publish_list(m, kit.ExtReg(SH, VIM, CONF)).Cmdy("", ice.CONTEXTS, ice.BASE) + _publish_list(m, kit.ExtReg(SH, VIM, CONF)) }}, ice.CONTEXTS: {Hand: func(m *ice.Message, arg ...string) { _publish_contexts(m, arg...) }}, mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) { m.Cmdy(nfs.DIR, arg[1:], nfs.DIR_CLI_FIELDS) }}, @@ -88,9 +79,10 @@ func init() { nfs.TRASH: {Hand: func(m *ice.Message, arg ...string) { nfs.Trash(m, path.Join(ice.USR_PUBLISH, m.Option(nfs.PATH))) }}, }, ctx.ConfAction(mdb.FIELD, nfs.PATH), aaa.RoleAction()), Hand: func(m *ice.Message, arg ...string) { if m.Option(nfs.DIR_ROOT, ice.USR_PUBLISH); len(arg) == 0 { - _publish_list(m) + _publish_list(m).Cmdy("", ice.CONTEXTS) } else { - m.Cmdy(nfs.DIR, arg[0], "time,size,path,hash,link,action", ice.OptionFields(mdb.DETAIL)) + m.Cmdy(nfs.DIR, arg[0], "time,path,size,hash,link,action", ice.OptionFields(mdb.DETAIL)) + web.PushImages(m, web.P(PUBLISH, arg[0])) } }}, }) diff --git a/core/code/vimer.go b/core/code/vimer.go index 28374814..52750ffd 100644 --- a/core/code/vimer.go +++ b/core/code/vimer.go @@ -109,6 +109,9 @@ func init() { for _, p := range kit.Split(kit.Select(m.Option(nfs.PATH), m.Option("paths"))) { nfs.DirDeepAll(m.Spawn(), nfs.PWD, p, func(value ice.Maps) { push("", value[nfs.PATH]) }, nfs.PATH) } + m.Cmd(XTERM).Table(func(value ice.Maps) { + push(ctx.INDEX, kit.Join([]string{"web.code.xterm", value[mdb.HASH], kit.Select(value[mdb.TYPE], value[mdb.NAME])})) + }) m.Cmd(ctx.COMMAND, mdb.SEARCH, ctx.COMMAND, ice.OptionFields(ctx.INDEX)).Table(func(value ice.Maps) { push(ctx.INDEX, value[ctx.INDEX]) }) m.Cmd(mdb.SEARCH, cli.SYSTEM, cli.OPENS, ice.OptionFields("type,name,text")).Sort("type,name,text").Table(func(value ice.Maps) { push(cli.OPENS, value[nfs.NAME]) }) default: @@ -169,7 +172,7 @@ func init() { 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(), "源码")) }) }}, - }, mdb.HashAction(mdb.SHORT, nfs.PATH, mdb.FIELD, "time,path"), web.DreamAction(), aaa.RoleAction(ctx.COMMAND)), Hand: func(m *ice.Message, arg ...string) { + }, aaa.RoleAction(ctx.COMMAND), web.DreamAction(), mdb.HashAction(mdb.SHORT, nfs.PATH, mdb.FIELD, "time,path")), Hand: func(m *ice.Message, arg ...string) { if m.Cmdy(INNER, arg); arg[0] != ctx.ACTION { kit.If(len(arg) > 1, func() { mdb.HashCreate(m.Spawn(), nfs.PATH, path.Join(kit.Slice(arg, 0, 2)...)) }) m.Action(nfs.MODULE, nfs.SCRIPT, nfs.SAVE, COMPILE, "show", "exec") diff --git a/core/code/xterm.go b/core/code/xterm.go index 6e55ca56..4d4af412 100644 --- a/core/code/xterm.go +++ b/core/code/xterm.go @@ -21,7 +21,7 @@ import ( func _xterm_get(m *ice.Message, h string) *xterm.XTerm { h = kit.Select(m.Option(mdb.HASH), h) m.Assert(h != "") - mdb.HashModify(m, mdb.TIME, m.Time(), web.VIEW, m.Option(ice.MSG_DAEMON)) + mdb.HashModify(m, mdb.TIME, m.Time(), cli.DAEMON, m.Option(ice.MSG_DAEMON)) return mdb.HashSelectTarget(m, h, func(value ice.Maps) ice.Any { text := strings.Split(value[mdb.TEXT], lex.NL) ls := kit.Split(strings.Split(kit.Select(nfs.SH, value[mdb.TYPE]), " # ")[0]) @@ -56,7 +56,7 @@ func _xterm_get(m *ice.Message, h string) *xterm.XTerm { }).(*xterm.XTerm) } func _xterm_echo(m *ice.Message, h string, str string) { - m.Options(ice.MSG_DAEMON, mdb.HashSelectField(m, h, web.VIEW)) + m.Options(ice.MSG_DAEMON, mdb.HashSelectField(m, h, cli.DAEMON)) m.Option(ice.LOG_DISABLE, ice.TRUE) web.PushNoticeGrow(m, h, str) } @@ -119,7 +119,7 @@ func init() { ctx.PROCESS: {Hand: func(m *ice.Message, arg ...string) { ctx.ProcessField(m, m.PrefixKey(), func() string { return m.Cmdx("", mdb.CREATE, arg) }, arg...) }}, - }, ctx.CmdAction(), ctx.ProcessAction(), web.DreamAction(), mdb.HashAction(mdb.FIELD, "time,hash,type,name,text,path,view,theme")), Hand: func(m *ice.Message, arg ...string) { + }, ctx.CmdAction(), ctx.ProcessAction(), web.DreamAction(), mdb.HashAction(mdb.FIELD, "time,hash,type,name,text,path,theme,daemon")), Hand: func(m *ice.Message, arg ...string) { if mdb.HashSelect(m, arg...); len(arg) == 0 { m.PushAction(web.OUTPUT, mdb.REMOVE).Action(mdb.CREATE, mdb.PRUNES) } else { diff --git a/misc/git/repos.go b/misc/git/repos.go index 2585e5e5..d269ba94 100644 --- a/misc/git/repos.go +++ b/misc/git/repos.go @@ -36,9 +36,14 @@ func _repos_insert(m *ice.Message, p string) { if repos, err := git.PlainOpen(p); err == nil { args := []string{REPOS, path.Base(p), nfs.PATH, p} if refer, err := repos.Head(); err == nil { - args = append(args, BRANCH, strings.TrimPrefix(refer.Name().String(), "refs/heads/")) + args = append(args, BRANCH, refer.Name().Short()) if commit, err := repos.CommitObject(refer.Hash()); err == nil { - args = append(args, mdb.TIME, commit.Author.When.Format(ice.MOD_TIME), COMMIT, commit.Message) + args = append(args, mdb.TIME, commit.Author.When.Format(ice.MOD_TIME), COMMENT, commit.Message) + } + } + if iter, err := repos.Tags(); err == nil { + if refer, err := iter.Next(); err == nil { + args = append(args, VERSION, refer.Name().Short()) } } if remote, err := repos.Remotes(); err == nil && len(remote) > 0 { @@ -89,7 +94,7 @@ func _repos_branch(m *ice.Message, repos *git.Repository) error { iter.ForEach(func(refer *plumbing.Reference) error { if commit, err := repos.CommitObject(refer.Hash()); err == nil { m.Push(mdb.TIME, commit.Author.When.Format(ice.MOD_TIME)) - m.Push(BRANCH, strings.TrimPrefix(refer.Name().String(), "refs/heads/")) + m.Push(BRANCH, refer.Name().Short()) m.Push(aaa.USERNAME, commit.Author.Name) m.Push(mdb.TEXT, commit.Message) } @@ -97,12 +102,8 @@ func _repos_branch(m *ice.Message, repos *git.Repository) error { }) return nil } -func _repos_log(m *ice.Message, branch *config.Branch, repos *git.Repository) error { - refer, err := repos.Reference(branch.Merge, true) - if err != nil { - return err - } - iter, err := repos.Log(&git.LogOptions{From: refer.Hash()}) +func _repos_log(m *ice.Message, hash plumbing.Hash, repos *git.Repository) error { + iter, err := repos.Log(&git.LogOptions{From: hash}) if err != nil { return err } @@ -400,7 +401,9 @@ func init() { LOG: {Hand: func(m *ice.Message, arg ...string) { repos := _repos_open(m, kit.Select(m.Option(REPOS), arg, 0)) if branch, err := repos.Branch(kit.Select(m.Option(BRANCH), arg, 1)); !m.Warn(err) { - _repos_log(m, branch, repos) + if refer, err := repos.Reference(branch.Merge, true); !m.Warn(err) { + _repos_log(m, refer.Hash(), repos) + } } }}, TAG: {Name: "tag version", Hand: func(m *ice.Message, arg ...string) { @@ -463,12 +466,12 @@ func init() { m.Push(REMOTE, kit.Select("", _remote.Config().URLs, 0)) } if refer, err := repos.Head(); err == nil { - m.Push(BRANCH, strings.TrimPrefix(refer.Name().String(), "refs/heads/")) + m.Push(BRANCH, refer.Name().Short()) m.Push(mdb.HASH, refer.Hash().String()) } if iter, err := repos.Tags(); err == nil { if refer, err := iter.Next(); err == nil { - m.Push(nfs.VERSION, strings.TrimPrefix(refer.Name().String(), "refs/tags/")) + m.Push(nfs.VERSION, refer.Name().Short()) } } if cfg, err := config.LoadConfig(config.GlobalScope); err == nil { @@ -512,6 +515,9 @@ func init() { mdb.HashRemove(m, m.Option(REPOS)) } }}, + 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(), "仓库")) }) + }}, web.DREAM_CREATE: {Hand: func(m *ice.Message, arg ...string) { kit.If(m.Option(REPOS), func(p string) { p = strings.Split(p, mdb.QS)[0] @@ -520,7 +526,7 @@ func init() { }) }}, code.INNER: {Hand: func(m *ice.Message, arg ...string) { _repos_inner(m, _repos_path, arg...) }}, - }, gdb.EventsAction(web.DREAM_CREATE), mdb.HashAction(mdb.SHORT, REPOS, mdb.FIELD, "time,repos,branch,commit,origin"), mdb.ClearOnExitHashAction()), Hand: func(m *ice.Message, arg ...string) { + }, gdb.EventsAction(web.DREAM_CREATE), web.DreamAction(), mdb.HashAction(mdb.SHORT, REPOS, mdb.FIELD, "time,repos,branch,version,comment,origin"), mdb.ClearOnExitHashAction()), Hand: func(m *ice.Message, arg ...string) { if len(arg) == 0 { mdb.HashSelect(m, arg...).Sort(REPOS).Action(CLONE, PULL, PUSH, STATUS) } else if len(arg) == 1 { @@ -528,7 +534,9 @@ func init() { } else if len(arg) == 2 { repos := _repos_open(m, arg[0]) if branch, err := repos.Branch(arg[1]); !m.Warn(err) { - _repos_log(m, branch, repos) + if refer, err := repos.Reference(branch.Merge, true); !m.Warn(err) { + _repos_log(m, refer.Hash(), repos) + } } } else if len(arg) == 3 { if repos := _repos_open(m, arg[0]); arg[2] == INDEX { diff --git a/misc/git/service.go b/misc/git/service.go index 0b818bf2..41ab442e 100644 --- a/misc/git/service.go +++ b/misc/git/service.go @@ -11,6 +11,7 @@ import ( "strconv" "strings" + "shylinux.com/x/go-git/v5/plumbing" "shylinux.com/x/go-git/v5/plumbing/transport/file" ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/aaa" @@ -56,6 +57,9 @@ func _service_repos(m *ice.Message, arg ...string) error { _service_writer(m, "# service=git-"+service+lex.NL, _git_cmds(m, service, "--stateless-rpc", "--advertise-refs", nfs.PT)) return nil } + if service == RECEIVE_PACK { + defer m.Cmd(Prefix(SERVICE), mdb.CREATE, mdb.NAME, path.Base(repos)) + } reader, err := _service_reader(m) if err != nil { return err @@ -106,6 +110,7 @@ func init() { } else if !nfs.Exists(m, repos) { m.Cmd(Prefix(SERVICE), mdb.CREATE, mdb.NAME, path.Base(repos)) } + case UPLOAD_PACK: if m.Warn(!nfs.Exists(m, repos), ice.ErrNotFound, arg[0]) { return @@ -139,7 +144,6 @@ func init() { os.Exit(128) } }}, - TOKEN: {Hand: func(m *ice.Message, arg ...string) { m.Cmdy(TOKEN, cli.MAKE) }}, code.INNER: {Hand: func(m *ice.Message, arg ...string) { _repos_inner(m, _service_path, arg...) }}, web.DREAM_INPUTS: {Hand: func(m *ice.Message, arg ...string) { switch arg[0] { @@ -147,17 +151,23 @@ func init() { mdb.HashSelect(m).Sort(REPOS).Cut("repos,branch,commit,time") } }}, - }, gdb.EventsAction(web.DREAM_INPUTS), mdb.HashAction(mdb.SHORT, REPOS, mdb.FIELD, "time,repos,branch,commit"), mdb.ClearOnExitHashAction()), Hand: func(m *ice.Message, arg ...string) { + }, gdb.EventsAction(web.DREAM_INPUTS), mdb.HashAction(mdb.SHORT, REPOS, mdb.FIELD, "time,repos,branch,version,comment"), mdb.ClearOnExitHashAction()), Hand: func(m *ice.Message, arg ...string) { if len(arg) == 0 { - mdb.HashSelect(m, arg...).Sort(REPOS).Action(mdb.CREATE, TOKEN) - m.Echo(strings.ReplaceAll(m.Cmdx("web.code.publish", ice.CONTEXTS), "app username", "dev username")) + mdb.HashSelect(m, arg...).Table(func(value ice.Maps) { + m.PushScript(kit.Format("git clone %s", tcp.PublishLocalhost(m, kit.Split(web.MergeURL2(m, "/x/"+value[REPOS]+".git"), mdb.QS)[0]))) + }).Sort(REPOS).Echo(strings.ReplaceAll(m.Cmdx("web.code.publish", ice.CONTEXTS), "app username", "dev username")) } else if len(arg) == 1 { _repos_branch(m, _repos_open(m, arg[0])) m.EchoScript(tcp.PublishLocalhost(m, kit.Split(web.MergeURL2(m, "/x/"+arg[0]), mdb.QS)[0])) } else if len(arg) == 2 { repos := _repos_open(m, arg[0]) - if branch, err := repos.Branch(arg[1]); !m.Warn(err) { - _repos_log(m, branch, repos) + if iter, err := repos.Branches(); err == nil { + iter.ForEach(func(refer *plumbing.Reference) error { + if refer.Name().Short() == arg[1] { + _repos_log(m, refer.Hash(), repos) + } + return nil + }) } } else if len(arg) == 3 { if repos := _repos_open(m, arg[0]); arg[2] == INDEX { diff --git a/misc/git/status.go b/misc/git/status.go index c6d89f14..07b85494 100644 --- a/misc/git/status.go +++ b/misc/git/status.go @@ -130,12 +130,13 @@ func init() { }) kit.If(m.Option(nfs.TO), func() { _git_cmd(m, CONFIG, "--global", "url."+m.Option(nfs.TO)+".insteadof", m.Option(nfs.FROM)) }) }}, - CONFIGS: {Name: "configs email username", Help: "配置", Hand: func(m *ice.Message, arg ...string) { + CONFIGS: {Name: "configs email* username*", Help: "配置", Hand: func(m *ice.Message, arg ...string) { + m.Cmd(nfs.DEFS, kit.HomePath(".gitconfig"), nfs.Template(m, "gitconfig", m.Option(aaa.USERNAME), m.Option(aaa.EMAIL))) mdb.Config(m, aaa.USERNAME, m.Option(aaa.USERNAME)) mdb.Config(m, aaa.EMAIL, m.Option(aaa.EMAIL)) }}, OAUTH: {Help: "授权", Hand: func(m *ice.Message, arg ...string) { - m.ProcessOpen(kit.MergeURL2(kit.Select(ice.Info.Make.Domain, _git_remote(m)), "/chat/cmd/web.code.git.token/gen/", tcp.HOST, m.Option(ice.MSG_USERWEB))) + m.ProcessOpen(kit.MergeURL2(kit.Select(ice.Info.Make.Domain, _git_remote(m)), web.ChatCmdPath(Prefix(TOKEN), "gen"), tcp.HOST, m.Option(ice.MSG_USERWEB))) }}, web.DREAM_TABLES: {Hand: func(m *ice.Message, arg ...string) { if m.Option(mdb.TYPE) != web.WORKER { @@ -153,7 +154,7 @@ func init() { } m.Push(mdb.TEXT, strings.Join(text, ", ")) }}, - }, gdb.EventAction(web.DREAM_TABLES), Prefix(REPOS), mdb.ImportantDataAction(), aaa.RoleAction()), Hand: func(m *ice.Message, arg ...string) { + }, aaa.RoleAction(), gdb.EventAction(web.DREAM_TABLES), Prefix(REPOS), mdb.ImportantDataAction()), Hand: func(m *ice.Message, arg ...string) { if len(arg) > 0 && arg[0] == ctx.ACTION { m.Cmdy(REPOS, arg) } else if config, err := config.LoadConfig(config.GlobalScope); err == nil && config.User.Email == "" && mdb.Config(m, aaa.EMAIL) == "" { diff --git a/misc/git/token.go b/misc/git/token.go index 2600b6a0..a0483fc8 100644 --- a/misc/git/token.go +++ b/misc/git/token.go @@ -5,7 +5,6 @@ import ( ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/aaa" - "shylinux.com/x/icebergs/base/cli" "shylinux.com/x/icebergs/base/lex" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" @@ -20,50 +19,26 @@ func init() { const ( GEN = "gen" SET = "set" - GET = "get" - SID = "sid" FILE = ".git-credentials" LOCAL = "http://localhost:9020" ) - create := func(m *ice.Message) string { - msg := m.Cmd(Prefix(TOKEN), m.Cmdx(Prefix(TOKEN), mdb.CREATE, aaa.USERNAME, m.Option(ice.MSG_USERNAME), TOKEN, kit.Hashs(mdb.UNIQ))) - return strings.Replace(web.UserHost(m), "://", kit.Format("://%s:%s@", m.Option(ice.MSG_USERNAME), msg.Append(TOKEN)), 1) - } Index.MergeCommands(ice.Commands{ - TOKEN: {Name: "token username auto prunes", Actions: ice.MergeActions(ice.Actions{ - ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { aaa.White(m, kit.Keys(TOKEN, SID)) }}, - cli.MAKE: {Hand: func(m *ice.Message, arg ...string) { - m.ProcessReplace(kit.MergeURL2(LOCAL, m.PrefixPath(SET), TOKEN, create(m))) - }}, + TOKEN: {Name: "token username auto prunes", Help: "令牌", Actions: ice.MergeActions(ice.Actions{ GEN: {Hand: func(m *ice.Message, arg ...string) { - m.ProcessReplace(kit.MergeURL2(m.Option(tcp.HOST), m.PrefixPath(SET), TOKEN, create(m))) - m.Debug("what %v", m.FormatMeta()) + msg := m.Cmd("", m.Option(ice.MSG_USERNAME)) + if msg.Append(mdb.TIME) < m.Time() { + msg = m.Cmd("", mdb.CREATE, aaa.USERNAME, m.Option(ice.MSG_USERNAME), TOKEN, kit.Hashs(mdb.UNIQ)).Cmd("", m.Option(ice.MSG_USERNAME)) + } + if !m.Warn(!strings.HasPrefix(m.Option(tcp.HOST), "http://localhost:"), ice.ErrNotRight, m.Option(tcp.HOST)) { + m.ProcessReplace(kit.MergeURL2(m.Option(tcp.HOST), web.ChatCmdPath(m.PrefixKey(), SET), TOKEN, strings.Replace(web.UserHost(m), "://", kit.Format("://%s:%s@", m.Option(ice.MSG_USERNAME), msg.Append(TOKEN)), 1))) + } }}, - web.PP(GEN): {Hand: func(m *ice.Message, arg ...string) { - m.ProcessReplace(kit.MergeURL2(m.Option(tcp.HOST), m.PrefixPath(SET), TOKEN, create(m))) - }}, - web.PP(SET): {Hand: func(m *ice.Message, arg ...string) { - defer web.RenderTemplate(m, "close.html") + SET: {Hand: func(m *ice.Message, arg ...string) { host, list := ice.Map{kit.ParseURL(m.Option(TOKEN)).Host: true}, []string{m.Option(TOKEN)} m.Cmd(nfs.CAT, kit.HomePath(FILE), func(line string) { kit.IfNoKey(host, kit.ParseURL(line).Host, func(p string) { list = append(list, line) }) }).Cmd(nfs.SAVE, kit.HomePath(FILE), strings.Join(list, lex.NL)+lex.NL) - }}, - web.PP(GET): {Hand: func(m *ice.Message, arg ...string) { - web.RenderOrigin(m.W, "*") - m.Cmd(nfs.CAT, kit.HomePath(FILE), func(text string) { - if u := kit.ParseURL(text); u.Host == arg[0] { - if p, ok := u.User.Password(); ok { - m.Echo(u.User.Username()).Echo(p) - web.RenderOrigin(m.W, u.Scheme+"://"+u.Host) - } - } - }) - }}, - web.PP(SID): {Hand: func(m *ice.Message, arg ...string) { - if len(arg) > 1 && m.Cmd(TOKEN, arg[0]).Append(TOKEN) == arg[1] { - web.RenderCookie(m.Echo(ice.OK), aaa.SessCreate(m, arg[0])) - } + m.ProcessClose() }}, }, mdb.HashAction(mdb.EXPIRE, mdb.MONTH, mdb.SHORT, aaa.USERNAME, mdb.FIELD, "time,username,token"))}, }) diff --git a/misc/git/total.go b/misc/git/total.go index 29a39e30..cf5a1a0c 100644 --- a/misc/git/total.go +++ b/misc/git/total.go @@ -84,7 +84,6 @@ func init() { } from, days, commit, adds, dels := "", 0, 0, 0, 0 kit.SplitKV(lex.NL, "commit:", _git_cmds(m, args...), func(text string, ls []string) { - m.Debug("what %v", ls) add, del := "0", "0" for _, v := range kit.Split(strings.TrimSpace(kit.Select("", ls, -1)), mdb.FS) { switch { diff --git a/option.go b/option.go index 6bb48fe0..619b885e 100644 --- a/option.go +++ b/option.go @@ -33,6 +33,11 @@ func (m *Message) OptionSplit(key ...string) (res []string) { kit.For(kit.Split(kit.Join(key)), func(k string) { res = append(res, m.Option(k)) }) return res } +func (m *Message) OptionArgs(key ...string) string { + res := []string{} + kit.For(kit.Split(kit.Join(key)), func(k string) { kit.If(m.Option(k), func(v string) { res = append(res, k, kit.Format("%q", v)) }) }) + return strings.Join(res, SP) +} func (m *Message) OptionCB(key string, cb ...Any) Any { kit.If(len(cb) > 0, func() { m.Optionv(kit.Keycb(kit.Select(m.CommandKey(), key)), cb...) }) return m.Optionv(kit.Keycb(kit.Select(m.CommandKey(), key))) @@ -101,3 +106,4 @@ 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) ProcessClose() { m.Process(PROCESS_CLOSE) }