diff --git a/.gitignore b/.gitignore index 180e8921..4a03b309 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ pack/ # Output of the go coverage tool, specifically when used with LiteIDE *.out +*.log # Dependency directories (remove the comment below to include it) # vendor/ diff --git a/base/ctx/cmd.go b/base/ctx/cmd.go index 1ff678e2..36dd9544 100644 --- a/base/ctx/cmd.go +++ b/base/ctx/cmd.go @@ -20,9 +20,6 @@ func _command_list(m *ice.Message, all bool, name string) { m.Push("name", kit.Format(cmd.Name)) m.Push("help", kit.Simple(cmd.Help)[0]) m.Push("meta", kit.Format(cmd.Meta)) - if len(cmd.List) == 0 { - _command_make(m, cmd) - } m.Push("list", kit.Format(cmd.List)) }) return @@ -45,51 +42,6 @@ func _command_list(m *ice.Message, all bool, name string) { m.Push("help", kit.Simple(v.Help)[0]) } } -func _command_make(m *ice.Message, cmd *ice.Command) { - var list []string - switch name := cmd.Name.(type) { - case []string, []interface{}: - list = kit.Split(kit.Simple(name)[0]) - default: - list = kit.Split(strings.Split(kit.Format(name), ";")[0]) - } - - button := false - for i, v := range list { - if i == 0 { - continue - } - switch ls := kit.Split(v, ":="); ls[0] { - case "[", "]": - case "auto": - cmd.List = append(cmd.List, kit.List(kit.MDB_INPUT, "button", "name", "查看", "value", "auto")...) - cmd.List = append(cmd.List, kit.List(kit.MDB_INPUT, "button", "name", "返回", "value", "Last")...) - button = true - default: - kind, value := kit.Select("text", "button", button), "" - if len(ls) == 3 { - kind, value = ls[1], ls[2] - } else if len(ls) == 2 { - if strings.Contains(v, "=") { - value = ls[1] - } else { - kind = ls[1] - } - } - if kind == "button" { - button = true - } - cmd.List = append(cmd.List, kit.List(kit.MDB_INPUT, kind, "name", ls[0], "value", value)...) - } - } - if len(cmd.List) == 0 { - cmd.List = append(cmd.List, kit.List(kit.MDB_INPUT, "text", "name", "path")...) - } - if !button { - cmd.List = append(cmd.List, kit.List(kit.MDB_INPUT, "button", "name", "查看")...) - cmd.List = append(cmd.List, kit.List(kit.MDB_INPUT, "button", "name", "返回")...) - } -} const COMMAND = "command" diff --git a/base/mdb/mdb.go b/base/mdb/mdb.go index 40a37e57..fe317078 100644 --- a/base/mdb/mdb.go +++ b/base/mdb/mdb.go @@ -35,6 +35,9 @@ func _hash_select(m *ice.Message, prefix, key, field, value string) { } fields := strings.Split(kit.Select("time,hash,type,name,text", m.Option(FIELDS)), ",") m.Richs(prefix, key, value, func(key string, val map[string]interface{}) { + if val[kit.MDB_META] != nil { + val = val[kit.MDB_META].(map[string]interface{}) + } if field != "" && field != kit.MDB_HASH && value != val[field] && value != kit.MDB_FOREACH { return } @@ -149,6 +152,9 @@ func _list_select(m *ice.Message, prefix, key, field, value string) { } m.Push("", val, fields, val[kit.MDB_META]) }) + if m.Option(FIELDS) != "detail" { + m.Sort(kit.MDB_ID, "int_r") + } } func _list_modify(m *ice.Message, prefix, key string, field, value string, arg ...string) { m.Grows(prefix, key, field, value, func(index int, value map[string]interface{}) { diff --git a/base/nfs/nfs.go b/base/nfs/nfs.go index 569ab10a..b578cf1e 100644 --- a/base/nfs/nfs.go +++ b/base/nfs/nfs.go @@ -218,6 +218,9 @@ func _file_copy(m *ice.Message, name string, from ...string) { } } func _file_link(m *ice.Message, name string, from string) { + if from == "" { + return + } os.MkdirAll(path.Dir(name), 0760) os.Remove(name) os.Link(from, name) diff --git a/base/web/route.go b/base/web/route.go index bfd1888a..49e5a5fe 100644 --- a/base/web/route.go +++ b/base/web/route.go @@ -47,7 +47,7 @@ func init() { ROUTE: {Name: ROUTE, Help: "路由器", Value: kit.Data(kit.MDB_SHORT, kit.MDB_ROUTE)}, }, Commands: map[string]*ice.Command{ - ROUTE: {Name: "route route=auto cmd=@key auto 启动 添加", Help: "路由", Action: map[string]*ice.Action{ + ROUTE: {Name: "route route cmd auto 启动 添加", Help: "路由", Action: map[string]*ice.Action{ "invite": {Name: "invite", Help: "添加", Hand: func(m *ice.Message, arg ...string) { m.Cmdy("web.code.install", "contexts", "base") }}, diff --git a/base/web/serve.go b/base/web/serve.go index 996f2e8b..f6df33ac 100644 --- a/base/web/serve.go +++ b/base/web/serve.go @@ -14,6 +14,7 @@ import ( "net/http" "net/url" "os" + "path" "strings" ) @@ -177,6 +178,11 @@ func _serve_main(m *ice.Message, w http.ResponseWriter, r *http.Request) bool { m.Info(" ") }() } + + if r.URL.Path == "/" && strings.Contains(r.Header.Get("User-Agent"), "curl") { + http.ServeFile(w, r, path.Join(m.Conf(SERVE, "meta.intshell.path"), m.Conf(SERVE, "meta.intshell.index"))) + return false + } } if strings.HasPrefix(r.URL.Path, "/debug") { @@ -243,11 +249,15 @@ func init() { "publish", true, ), + "intshell", kit.Dict( + "path", "usr/intshell", "index", "index.sh", "require", ".ish/pluged", + "repos", "https://github.com/shylinux/volcanos", "branch", "master", + ), + "static", kit.Dict("/", "usr/volcanos/"), - "volcanos", kit.Dict("path", "usr/volcanos", "branch", "master", - "repos", "https://github.com/shylinux/volcanos", - "require", ".ish/pluged", - "refresh", "5", + "volcanos", kit.Dict("refresh", "5", + "path", "usr/volcanos", "require", ".ish/pluged", + "repos", "https://github.com/shylinux/volcanos", "branch", "master", ), "page", kit.Dict( "index", "usr/volcanos/page/index.html", "share", "usr/volcanos/page/share.html", diff --git a/base/web/spide.go b/base/web/spide.go index f6fc1f87..176447e3 100644 --- a/base/web/spide.go +++ b/base/web/spide.go @@ -2,6 +2,7 @@ package web import ( ice "github.com/shylinux/icebergs" + "github.com/shylinux/icebergs/base/cli" "github.com/shylinux/icebergs/base/mdb" "github.com/shylinux/icebergs/base/tcp" kit "github.com/shylinux/toolkits" @@ -203,6 +204,10 @@ func init() { // 请求地址 uri, arg := arg[0], arg[1:] + if strings.HasPrefix(uri, "ftp") { + m.Cmdy(cli.SYSTEM, "wget", uri) + return + } // if n := m.Cmd("spide_rewrite", uri).Append("to"); n != "" && n != uri { // m.Logs("rewrite", "from", uri, "to", n) // uri = n diff --git a/core/code/code.go b/core/code/code.go index ed2a9b1a..bb151c2f 100644 --- a/core/code/code.go +++ b/core/code/code.go @@ -1,210 +1,27 @@ package code import ( - "net/http" - ice "github.com/shylinux/icebergs" - "github.com/shylinux/icebergs/base/cli" - "github.com/shylinux/icebergs/base/mdb" - "github.com/shylinux/icebergs/base/nfs" "github.com/shylinux/icebergs/base/web" - kit "github.com/shylinux/toolkits" - - "net/url" - "os" - "path" - "runtime" - "strings" ) -const ( - VEDIO = "vedio" - QRCODE = "qrcode" -) +const CODE = "code" -const ( // CODE - // INSTALL = "_install" - PREPARE = "_prepare" - PROJECT = "_project" -) - -var Index = &ice.Context{Name: "code", Help: "编程中心", - Configs: map[string]*ice.Config{ - "_install": {Name: "install", Help: "安装", Value: kit.Data( - "path", "usr/install", "target", "usr/local", - "linux", "https://dl.google.com/go/go1.14.2.linux-amd64.tar.gz", - "darwin", "https://dl.google.com/go/go1.14.6.darwin-amd64.tar.gz", - "windows", "https://golang.google.cn/dl/go1.14.6.windows-amd64.zip", - )}, - PREPARE: {Name: "prepare", Help: "配置", Value: kit.Data("path", "usr/prepare", - "script", ".ish/pluged/golang/init.sh", "export", kit.Dict( - "GOPROXY", "https://goproxy.cn,direct", - "GOPRIVATE", "https://github.com", - ), - )}, - PROJECT: {Name: "project", Help: "项目", Value: kit.Data("path", "usr/project")}, - - "login": {Name: "login", Help: "终端接入", Value: kit.Data()}, - }, +var Index = &ice.Context{Name: CODE, Help: "编程中心", + Configs: map[string]*ice.Config{}, Commands: map[string]*ice.Command{ ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Load() - m.Cmd(mdb.ENGINE, mdb.CREATE, BENCH) - m.Conf(INSTALL, "meta.contexts", _contexts) - }}, - ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Save(INSTALL) - }}, - - "_install": {Name: "install url 安装:button", Help: "安装", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - target := m.Conf("_install", kit.Keys("meta", runtime.GOOS)) - - p := path.Join(m.Conf("_install", "meta.path"), path.Base(target)) - if _, e := os.Stat(p); e != nil { - // 下载 - msg := m.Cmd(web.SPIDE, "dev", web.CACHE, http.MethodGet, target) - m.Cmd(web.CACHE, web.WATCH, msg.Append(web.DATA), p) - } - - os.MkdirAll(m.Conf("_install", kit.Keys("meta.target")), ice.MOD_DIR) - m.Cmdy(cli.SYSTEM, "tar", "xvf", p, "-C", m.Conf("_install", kit.Keys("meta.target"))) - }}, - PREPARE: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - export := []string{} - kit.Fetch(m.Confv(PREPARE, "meta.export"), func(key string, val string) { - export = append(export, key+"="+val) - }) - - m.Cmd(nfs.SAVE, m.Conf(PREPARE, "meta.script"), kit.Format(` -export GOROOT=%s GOPATH=%s:$GOPATH GOBIN=%s -export PATH=$GOBIN:$GOROOT/bin:$PATH -export %s -`, kit.Path(m.Conf("_install", kit.Keys("meta.target")), "go"), kit.Path("src"), kit.Path("bin"), strings.Join(export, " "))) - }}, - PROJECT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - }}, - - "login": {Name: "login key", Help: "登录", Meta: kit.Dict( - "detail", []string{"编辑", "删除", "清理", "清空"}, - ), Action: map[string]*ice.Action{}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - if len(arg) > 0 && arg[0] == "action" { - switch arg[1] { - case "modify", "编辑": - m.Richs(cmd, nil, m.Option("key"), func(key string, value map[string]interface{}) { - m.Logs(ice.LOG_MODIFY, cmd, key, "field", arg[2], "value", kit.Value(value, arg[2]), "->", arg[3]) - kit.Value(value, arg[2], arg[3]) - }) - - case "delete", "删除": - m.Logs(ice.LOG_DELETE, cmd, m.Option("key"), "value", m.Conf(cmd, kit.Keys(kit.MDB_HASH, m.Option("key")))) - m.Conf(cmd, kit.Keys(kit.MDB_HASH, m.Option("key")), "") - - case "prune", "清理": - m.Cmdy(cmd, "prune") - - case "clear", "清空": - m.Cmdy(cmd, "prune", "all") - } - return - } - - switch kit.Select("list", arg, 0) { - case "init": - if m.Option("sid") != "" && m.Conf(cmd, []string{kit.MDB_HASH, m.Option("sid"), "status"}) != "" { - // 复用会话 - m.Conf(cmd, []string{kit.MDB_HASH, m.Option("sid"), "status"}, "login") - m.Logs(ice.LOG_AUTH, "sid", m.Option("sid")) - m.Echo(m.Option("sid")) - return - } - - you := m.Conf(web.SHARE, kit.Keys(kit.MDB_HASH, m.Option("share"), "name")) - // 添加会话 - h := m.Rich(cmd, nil, kit.Dict( - "type", kit.Select("zsh", arg, 1), - "status", "login", - "you", you, - "pwd", m.Option("pwd"), - "pid", m.Option("pid"), - "pane", m.Option("pane"), - "hostname", m.Option("hostname"), - "username", m.Option("username"), - )) - m.Logs(ice.LOG_AUTH, "sid", h, "you", you) - m.Echo(h) - - case "exit": - // 退出会话 - m.Richs(cmd, nil, m.Option("sid"), func(key string, value map[string]interface{}) { - m.Logs(ice.LOG_AUTH, "sid", m.Option("sid")) - value["status"] = "logout" - m.Echo(key) - }) - - case "prune": - list := []string{} - m.Richs(cmd, nil, "*", func(key string, value map[string]interface{}) { - if len(arg) > 1 && arg[1] == "all" || value["status"] == "logout" { - list = append(list, key) - } - }) - - // 清理会话 - kit.Fetch(list, func(index int, value string) { - m.Logs(ice.LOG_DELETE, "login", value, "value", m.Conf(cmd, kit.Keys(kit.MDB_HASH, value))) - m.Conf(cmd, kit.Keys(kit.MDB_HASH, value), "") - }) - m.Echo("%d", len(list)) - - case "list": - // 会话列表 - m.Richs("login", nil, "*", func(key string, value map[string]interface{}) { - m.Push(key, value, []string{"time", "key", "type", "status", "you"}) - pwd := strings.Split(kit.Format(value["pwd"]), "/") - if len(pwd) > 3 { - m.Push("pwd", strings.Join(pwd[len(pwd)-3:len(pwd)], "/")) - } else { - m.Push("pwd", value["pwd"]) - } - m.Push(key, value, []string{"pid", "pane", "hostname", "username"}) - }) - - default: - // 会话详情 - m.Richs(cmd, nil, arg[0], func(key string, value map[string]interface{}) { - m.Push("detail", value) - }) - } - }}, - - "/miss/": {Name: "/miss/", Help: "任务", Action: map[string]*ice.Action{ - "pwd": {Name: "pwd", Help: "pwd", Hand: func(m *ice.Message, arg ...string) { - m.Render(ice.RENDER_RESULT) - m.Echo("hello world\n") - }}, - }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - u, e := url.QueryUnescape(m.Option("arg")) - m.Assert(e) - args := kit.Split(u) - if len(arg) == 0 || arg[0] == "" { - return - } - - m.Render(ice.RENDER_RESULT) - if m.Cmdy(arg, args); len(m.Resultv()) == 0 { - m.Table() - } + m.Conf(PUBLISH, "meta.contexts", _contexts) }}, + ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Save() }}, }, } func init() { web.Index.Register(Index, &web.Frame{}, - INSTALL, - COMPILE, - UPGRADE, - PUBLISH, - BENCH, - PPROF, + INSTALL, COMPILE, PUBLISH, UPGRADE, + INNER, VIMER, BENCH, PPROF, + C, SH, GO, SHY, JS, ) } diff --git a/core/code/inner.go b/core/code/inner.go index 90e36526..cf31f215 100644 --- a/core/code/inner.go +++ b/core/code/inner.go @@ -46,10 +46,7 @@ func _vimer_save(m *ice.Message, ext, file, dir string, text string) { } } -const ( - INNER = "inner" - VIMER = "vimer" -) +const INNER = "inner" func init() { Index.Merge(&ice.Context{ @@ -84,23 +81,6 @@ func init() { } _inner_list(m, _inner_ext(arg[1]), arg[1], arg[0]) }}, - VIMER: {Name: "vimer path=usr/demo file=hi.sh line=1 刷新:button=auto 保存:button 运行:button 项目:button", Help: "编辑器", Meta: kit.Dict( - "display", "/plugin/local/code/vimer.js", "style", "editor", - ), Action: map[string]*ice.Action{ - web.UPLOAD: {Name: "upload path name", Help: "上传", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(web.CACHE, web.UPLOAD) - m.Cmdy(web.CACHE, web.WATCH, m.Option(web.DATA), path.Join(m.Option("path"), m.Option("name"))) - }}, - nfs.SAVE: {Name: "save type file path", Help: "保存", Hand: func(m *ice.Message, arg ...string) { - _vimer_save(m, arg[0], arg[1], arg[2], m.Option("content")) - }}, - - "cmd": {Name: "cmd type file path", Help: "命令", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(arg) - }}, - }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Cmdy(INNER, arg) - }}, }, Configs: map[string]*ice.Config{ INNER: {Name: "inner", Help: "阅读器", Value: kit.Data( diff --git a/core/code/install.go b/core/code/install.go index 1be6b08a..eb49a790 100644 --- a/core/code/install.go +++ b/core/code/install.go @@ -9,37 +9,11 @@ import ( "github.com/shylinux/icebergs/base/web" kit "github.com/shylinux/toolkits" - "fmt" "os" "path" "strings" ) -var _contexts = kit.Dict( - "tmux", ` -# 终端环境 -curl -fLo /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-8.repo && yum -y update -yum install -y tmux vim -`, - "base", ` -# 生产环境 -mkdir contexts; cd contexts -export ctx_dev={{.Option "httphost"}} ctx_log=/dev/stdout; curl $ctx_dev/publish/ice.sh |sh -bin/ice.sh`, - "miss", ` -# 开发环境 -yum install -y make git go -mkdir ~/.ssh &>/dev/null; touch ~/.ssh/config; [ -z "$(cat ~/.ssh/config|grep 'HOST {{.Option "hostname"}}')" ] && echo -e "HOST {{.Option "hostname"}}\n Port 9030" >> ~/.ssh/config -export ISH_CONF_HUB_PROXY={{.Option "userhost"}}:.ish/pluged/ -git clone $ISH_CONF_HUB_PROXY/github.com/shylinux/contexts && cd contexts -source etc/miss.sh - -touch ~/.gitconfig; [ -z "$(cat ~/.gitconfig|grep '\[url \"{{.Option "userhost"}}')" ] && echo -e "[url \"{{.Option "userhost"}}:ish/pluged/\"]\n insteadOf=\"https://github.com/\"\n" >> ~/.gitconfig -git clone https://github.com/shylinux/contexts && cd contexts -source etc/miss.sh -`, -) - const INSTALL = "install" func init() { @@ -47,39 +21,32 @@ func init() { Configs: map[string]*ice.Config{ INSTALL: {Name: INSTALL, Help: "安装", Value: kit.Data( kit.MDB_SHORT, kit.MDB_NAME, kit.MDB_PATH, "usr/install", - "contexts", _contexts, + kit.MDB_FIELD, "time,step,size,total,name,link", )}, }, Commands: map[string]*ice.Command{ - INSTALL: {Name: "install name=auto port=auto path=auto auto", Help: "安装", Meta: kit.Dict(), Action: map[string]*ice.Action{ - "contexts": {Name: "contexts", Help: "环境", Hand: func(m *ice.Message, arg ...string) { - u := kit.ParseURL(m.Option(ice.MSG_USERWEB)) - m.Option("httphost", fmt.Sprintf("%s://%s:%s", u.Scheme, strings.Split(u.Host, ":")[0], kit.Select(kit.Select("80", "443", u.Scheme == "https"), strings.Split(u.Host, ":"), 1))) - m.Option("hostport", fmt.Sprintf("%s:%s", strings.Split(u.Host, ":")[0], kit.Select(kit.Select("80", "443", u.Scheme == "https"), strings.Split(u.Host, ":"), 1))) - m.Option("hostname", strings.Split(u.Host, ":")[0]) - - m.Option("userhost", fmt.Sprintf("%s@%s", m.Option(ice.MSG_USERNAME), strings.Split(u.Host, ":")[0])) - m.Option("hostpath", kit.Path("./.ish/pluged")) - - if buf, err := kit.Render(m.Conf(INSTALL, kit.Keys("meta.contexts", kit.Select("base", arg, 0))), m); m.Assert(err) { - m.Cmdy("web.wiki.spark", "shell", string(buf)) - } - }}, + INSTALL: {Name: "install name port path auto", Help: "安装", Meta: kit.Dict(), Action: map[string]*ice.Action{ "download": {Name: "download link", Help: "下载", Hand: func(m *ice.Message, arg ...string) { name := path.Base(arg[0]) - if m.Richs(INSTALL, "", name, func(key string, value map[string]interface{}) { - if _, e := os.Stat(path.Join(m.Conf(INSTALL, kit.META_PATH), kit.Format(value[kit.MDB_NAME]))); e == nil { - m.Push(key, value, []string{kit.MDB_TIME, kit.MDB_STEP, kit.MDB_SIZE, kit.MDB_TOTAL, kit.MDB_NAME, kit.MDB_LINK}) - m.Option("_process", "_progress") + p := path.Join(m.Conf(INSTALL, kit.META_PATH), name) + + m.Option("_process", "_progress") + m.Option(mdb.FIELDS, m.Conf(INSTALL, kit.META_FIELD)) + if m.Cmd(mdb.SELECT, m.Prefix(INSTALL), "", mdb.HASH, kit.MDB_NAME, name).Table(func(index int, value map[string]string, head []string) { + if _, e := os.Stat(p); e == nil { + m.Push("", value, kit.Split(m.Option(mdb.FIELDS))) } - }) != nil && len(m.Appendv(kit.MDB_NAME)) > 0 { - // 已经下载 - return + }); len(m.Appendv(kit.MDB_NAME)) > 0 { + return // 已经下载 } + // 占位 + m.Cmd(nfs.SAVE, p, "") + // 进度 m.Cmd(mdb.INSERT, m.Prefix(INSTALL), "", mdb.HASH, kit.MDB_NAME, name, kit.MDB_LINK, arg[0]) m.Richs(INSTALL, "", name, func(key string, value map[string]interface{}) { + value = value[kit.MDB_META].(map[string]interface{}) m.Optionv("progress", func(size int, total int) { s := size * 100 / total if s != kit.Int(value[kit.MDB_STEP]) && s%10 == 0 { @@ -89,23 +56,11 @@ func init() { }) }) - // 占位 - p := path.Join(m.Conf(INSTALL, kit.META_PATH), name) - if strings.Contains(p, "/") { - os.MkdirAll(path.Base(p), ice.MOD_DIR) - } - m.Cmd(cli.SYSTEM, "touch", p) - - m.Option("_process", "_progress") m.Gos(m, func(m *ice.Message) { // 下载 m.Option(cli.CMD_DIR, m.Conf(INSTALL, kit.META_PATH)) - if strings.HasPrefix(arg[0], "ftp") { - m.Cmdy(cli.SYSTEM, "wget", arg[0]) - } else { - msg := m.Cmd(web.SPIDE, web.SPIDE_DEV, web.SPIDE_CACHE, web.SPIDE_GET, arg[0]) - m.Cmdy(nfs.LINK, p, msg.Append(kit.MDB_FILE)) - } + msg := m.Cmd(web.SPIDE, web.SPIDE_DEV, web.SPIDE_CACHE, web.SPIDE_GET, arg[0]) + m.Cmdy(nfs.LINK, p, msg.Append(kit.MDB_FILE)) // 解压 m.Cmd(cli.SYSTEM, "tar", "xvf", name) @@ -117,7 +72,7 @@ func init() { case func(string): cb(p) default: - if m.Cmdy(cli.SYSTEM, "./configure", "--prefix="+kit.Path(path.Join(p, INSTALL)), arg[1:]); m.Append(cli.CMD_CODE) != "0" { + if m.Cmdy(cli.SYSTEM, "./configure", "--prefix="+kit.Path(path.Join(p, kit.Select("_install", m.Option("install")))), arg[1:]); m.Append(cli.CMD_CODE) != "0" { return } } @@ -125,16 +80,16 @@ func init() { if m.Cmdy(cli.SYSTEM, "make", "-j8"); m.Append(cli.CMD_CODE) != "0" { return } - if m.Cmdy(cli.SYSTEM, "make", "PREFIX="+kit.Path(path.Join(p, INSTALL)), "install"); m.Append(cli.CMD_CODE) != "0" { - return - } + + m.Cmdy(cli.SYSTEM, "mv", "INSTALL", "INSTALLS") + m.Cmdy(cli.SYSTEM, "make", "PREFIX="+kit.Path(path.Join(p, kit.Select("_install", m.Option("install")))), "install") }}, "spawn": {Name: "spawn link", Help: "新建", Hand: func(m *ice.Message, arg ...string) { port := m.Cmdx(tcp.PORT, "select") target := path.Join(m.Conf(cli.DAEMON, kit.META_PATH), port) source := path.Join(m.Conf(INSTALL, kit.META_PATH), kit.TrimExt(arg[0])) - m.Cmd(nfs.DIR, path.Join(source, kit.Select("install", m.Option("install")))).Table(func(index int, value map[string]string, head []string) { + m.Cmd(nfs.DIR, path.Join(source, kit.Select("_install", m.Option("install")))).Table(func(index int, value map[string]string, head []string) { m.Cmd(cli.SYSTEM, "cp", "-r", strings.TrimSuffix(value[kit.MDB_PATH], "/"), target) }) m.Echo(target) @@ -155,34 +110,30 @@ func init() { }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { if len(arg) == 0 { // 源码列表 - m.Option(mdb.FIELDS, "time,step,size,total,name,link") + m.Option(mdb.FIELDS, m.Conf(INSTALL, kit.META_FIELD)) m.Cmdy(mdb.SELECT, m.Prefix(INSTALL), "", mdb.HASH) - m.Sort(kit.MDB_TIME, "time_r") return } arg[0] = path.Base(arg[0]) if key := strings.Split(strings.Split(arg[0], "-")[0], ".")[0]; len(arg) == 1 { - // 服务列表 u := kit.ParseURL(m.Option(ice.MSG_USERWEB)) m.Cmd(cli.DAEMON).Table(func(index int, value map[string]string, head []string) { + // 服务列表 if strings.Contains(value[kit.MDB_NAME], key) { m.Push(kit.MDB_TIME, value[kit.MDB_TIME]) m.Push(kit.MDB_PORT, path.Base(value[kit.MDB_DIR])) m.Push(kit.MDB_STATUS, value[kit.MDB_STATUS]) m.Push(kit.MDB_NAME, value[kit.MDB_NAME]) - m.Push(kit.MDB_LINK, m.Cmdx(mdb.RENDER, web.RENDER.A, - kit.Format("http://%s:%s", u.Hostname(), path.Base(value[kit.MDB_DIR])))) + m.PushRender(kit.MDB_LINK, "a", kit.Format("http://%s:%s", u.Hostname(), path.Base(value[kit.MDB_DIR]))) } }) - m.Sort(kit.MDB_TIME, "time_r") return } // 目录列表 m.Option(nfs.DIR_ROOT, path.Join(m.Conf(cli.DAEMON, kit.META_PATH), arg[1])) m.Cmdy(nfs.DIR, kit.Select("./", arg, 2)) - m.Sort(kit.MDB_TIME, "time_r") }}, }, }, nil) diff --git a/core/code/publish.go b/core/code/publish.go index 9bf17d01..716945a5 100644 --- a/core/code/publish.go +++ b/core/code/publish.go @@ -10,6 +10,7 @@ import ( "os" "path" "runtime" + "strings" ) const PUBLISH = "publish" @@ -37,10 +38,24 @@ func init() { Configs: map[string]*ice.Config{ PUBLISH: {Name: PUBLISH, Help: "发布", Value: kit.Data( kit.MDB_SHORT, kit.MDB_NAME, kit.MDB_PATH, "usr/publish", + "contexts", _contexts, )}, }, Commands: map[string]*ice.Command{ PUBLISH: {Name: "publish path=auto auto 火山架 冰山架 神农架", Help: "发布", Action: map[string]*ice.Action{ + "contexts": {Name: "contexts", Help: "环境", Hand: func(m *ice.Message, arg ...string) { + u := kit.ParseURL(m.Option(ice.MSG_USERWEB)) + m.Option("httphost", fmt.Sprintf("%s://%s:%s", u.Scheme, strings.Split(u.Host, ":")[0], kit.Select(kit.Select("80", "443", u.Scheme == "https"), strings.Split(u.Host, ":"), 1))) + m.Option("hostport", fmt.Sprintf("%s:%s", strings.Split(u.Host, ":")[0], kit.Select(kit.Select("80", "443", u.Scheme == "https"), strings.Split(u.Host, ":"), 1))) + m.Option("hostname", strings.Split(u.Host, ":")[0]) + + m.Option("userhost", fmt.Sprintf("%s@%s", m.Option(ice.MSG_USERNAME), strings.Split(u.Host, ":")[0])) + m.Option("hostpath", kit.Path("./.ish/pluged")) + + if buf, err := kit.Render(m.Conf(INSTALL, kit.Keys("meta.contexts", kit.Select("base", arg, 0))), m); m.Assert(err) { + m.Cmdy("web.wiki.spark", "shell", string(buf)) + } + }}, "ish": {Name: "ish", Help: "神农架", Hand: func(m *ice.Message, arg ...string) { _publish_file(m, "etc/conf/tmux.conf") m.Option(nfs.DIR_REG, ".*\\.(sh|vim|conf)") @@ -64,3 +79,28 @@ func init() { }, }, nil) } + +var _contexts = kit.Dict( + "tmux", ` +# 终端环境 +curl -fLo /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-8.repo && yum -y update +yum install -y tmux +`, + "base", ` +# 生产环境 +mkdir contexts; cd contexts +export ctx_dev={{.Option "httphost"}} ctx_log=/dev/stdout; curl $ctx_dev/publish/ice.sh |sh +bin/ice.sh`, + "miss", ` +# 开发环境 +yum install -y make git vim go +mkdir ~/.ssh &>/dev/null; touch ~/.ssh/config; [ -z "$(cat ~/.ssh/config|grep 'HOST {{.Option "hostname"}}')" ] && echo -e "HOST {{.Option "hostname"}}\n Port 9030" >> ~/.ssh/config +export ISH_CONF_HUB_PROXY={{.Option "userhost"}}:.ish/pluged/ +git clone $ISH_CONF_HUB_PROXY/github.com/shylinux/contexts && cd contexts +source etc/miss.sh + +touch ~/.gitconfig; [ -z "$(cat ~/.gitconfig|grep '\[url \"{{.Option "userhost"}}')" ] && echo -e "[url \"{{.Option "userhost"}}:ish/pluged/\"]\n insteadOf=\"https://github.com/\"\n" >> ~/.gitconfig +git clone https://github.com/shylinux/contexts && cd contexts +source etc/miss.sh +`, +) diff --git a/core/code/trash.go b/core/code/trash.go new file mode 100644 index 00000000..99d1fe9b --- /dev/null +++ b/core/code/trash.go @@ -0,0 +1,188 @@ +package code + +import ( + "net/http" + + ice "github.com/shylinux/icebergs" + "github.com/shylinux/icebergs/base/cli" + "github.com/shylinux/icebergs/base/nfs" + "github.com/shylinux/icebergs/base/web" + kit "github.com/shylinux/toolkits" + + "net/url" + "os" + "path" + "runtime" + "strings" +) + +const ( // CODE + // INSTALL = "_install" + PREPARE = "_prepare" + PROJECT = "_project" +) + +const TRASH = "trash" + +func init() { + Index.Merge(&ice.Context{ + Configs: map[string]*ice.Config{ + "_install": {Name: "install", Help: "安装", Value: kit.Data( + "path", "usr/install", "target", "usr/local", + "linux", "https://dl.google.com/go/go1.14.2.linux-amd64.tar.gz", + "darwin", "https://dl.google.com/go/go1.14.6.darwin-amd64.tar.gz", + "windows", "https://golang.google.cn/dl/go1.14.6.windows-amd64.zip", + )}, + PREPARE: {Name: "prepare", Help: "配置", Value: kit.Data("path", "usr/prepare", + "script", ".ish/pluged/golang/init.sh", "export", kit.Dict( + "GOPROXY", "https://goproxy.cn,direct", + "GOPRIVATE", "https://github.com", + ), + )}, + PROJECT: {Name: "project", Help: "项目", Value: kit.Data("path", "usr/project")}, + + "login": {Name: "login", Help: "终端接入", Value: kit.Data()}, + }, + Commands: map[string]*ice.Command{ + "_install": {Name: "install url 安装:button", Help: "安装", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + target := m.Conf("_install", kit.Keys("meta", runtime.GOOS)) + + p := path.Join(m.Conf("_install", "meta.path"), path.Base(target)) + if _, e := os.Stat(p); e != nil { + // 下载 + msg := m.Cmd(web.SPIDE, "dev", web.CACHE, http.MethodGet, target) + m.Cmd(web.CACHE, web.WATCH, msg.Append(web.DATA), p) + } + + os.MkdirAll(m.Conf("_install", kit.Keys("meta.target")), ice.MOD_DIR) + m.Cmdy(cli.SYSTEM, "tar", "xvf", p, "-C", m.Conf("_install", kit.Keys("meta.target"))) + }}, + PREPARE: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + export := []string{} + kit.Fetch(m.Confv(PREPARE, "meta.export"), func(key string, val string) { + export = append(export, key+"="+val) + }) + + m.Cmd(nfs.SAVE, m.Conf(PREPARE, "meta.script"), kit.Format(` +export GOROOT=%s GOPATH=%s:$GOPATH GOBIN=%s +export PATH=$GOBIN:$GOROOT/bin:$PATH +export %s +`, kit.Path(m.Conf("_install", kit.Keys("meta.target")), "go"), kit.Path("src"), kit.Path("bin"), strings.Join(export, " "))) + }}, + PROJECT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + }}, + + "login": {Name: "login key", Help: "登录", Meta: kit.Dict( + "detail", []string{"编辑", "删除", "清理", "清空"}, + ), Action: map[string]*ice.Action{}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + if len(arg) > 0 && arg[0] == "action" { + switch arg[1] { + case "modify", "编辑": + m.Richs(cmd, nil, m.Option("key"), func(key string, value map[string]interface{}) { + m.Logs(ice.LOG_MODIFY, cmd, key, "field", arg[2], "value", kit.Value(value, arg[2]), "->", arg[3]) + kit.Value(value, arg[2], arg[3]) + }) + + case "delete", "删除": + m.Logs(ice.LOG_DELETE, cmd, m.Option("key"), "value", m.Conf(cmd, kit.Keys(kit.MDB_HASH, m.Option("key")))) + m.Conf(cmd, kit.Keys(kit.MDB_HASH, m.Option("key")), "") + + case "prune", "清理": + m.Cmdy(cmd, "prune") + + case "clear", "清空": + m.Cmdy(cmd, "prune", "all") + } + return + } + + switch kit.Select("list", arg, 0) { + case "init": + if m.Option("sid") != "" && m.Conf(cmd, []string{kit.MDB_HASH, m.Option("sid"), "status"}) != "" { + // 复用会话 + m.Conf(cmd, []string{kit.MDB_HASH, m.Option("sid"), "status"}, "login") + m.Logs(ice.LOG_AUTH, "sid", m.Option("sid")) + m.Echo(m.Option("sid")) + return + } + + you := m.Conf(web.SHARE, kit.Keys(kit.MDB_HASH, m.Option("share"), "name")) + // 添加会话 + h := m.Rich(cmd, nil, kit.Dict( + "type", kit.Select("zsh", arg, 1), + "status", "login", + "you", you, + "pwd", m.Option("pwd"), + "pid", m.Option("pid"), + "pane", m.Option("pane"), + "hostname", m.Option("hostname"), + "username", m.Option("username"), + )) + m.Logs(ice.LOG_AUTH, "sid", h, "you", you) + m.Echo(h) + + case "exit": + // 退出会话 + m.Richs(cmd, nil, m.Option("sid"), func(key string, value map[string]interface{}) { + m.Logs(ice.LOG_AUTH, "sid", m.Option("sid")) + value["status"] = "logout" + m.Echo(key) + }) + + case "prune": + list := []string{} + m.Richs(cmd, nil, "*", func(key string, value map[string]interface{}) { + if len(arg) > 1 && arg[1] == "all" || value["status"] == "logout" { + list = append(list, key) + } + }) + + // 清理会话 + kit.Fetch(list, func(index int, value string) { + m.Logs(ice.LOG_DELETE, "login", value, "value", m.Conf(cmd, kit.Keys(kit.MDB_HASH, value))) + m.Conf(cmd, kit.Keys(kit.MDB_HASH, value), "") + }) + m.Echo("%d", len(list)) + + case "list": + // 会话列表 + m.Richs("login", nil, "*", func(key string, value map[string]interface{}) { + m.Push(key, value, []string{"time", "key", "type", "status", "you"}) + pwd := strings.Split(kit.Format(value["pwd"]), "/") + if len(pwd) > 3 { + m.Push("pwd", strings.Join(pwd[len(pwd)-3:len(pwd)], "/")) + } else { + m.Push("pwd", value["pwd"]) + } + m.Push(key, value, []string{"pid", "pane", "hostname", "username"}) + }) + + default: + // 会话详情 + m.Richs(cmd, nil, arg[0], func(key string, value map[string]interface{}) { + m.Push("detail", value) + }) + } + }}, + + "/miss/": {Name: "/miss/", Help: "任务", Action: map[string]*ice.Action{ + "pwd": {Name: "pwd", Help: "pwd", Hand: func(m *ice.Message, arg ...string) { + m.Render(ice.RENDER_RESULT) + m.Echo("hello world\n") + }}, + }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + u, e := url.QueryUnescape(m.Option("arg")) + m.Assert(e) + args := kit.Split(u) + if len(arg) == 0 || arg[0] == "" { + return + } + + m.Render(ice.RENDER_RESULT) + if m.Cmdy(arg, args); len(m.Resultv()) == 0 { + m.Table() + } + }}, + }, + }, nil) +} diff --git a/core/code/vimer.go b/core/code/vimer.go new file mode 100644 index 00000000..6e0ac2bb --- /dev/null +++ b/core/code/vimer.go @@ -0,0 +1,37 @@ +package code + +import ( + ice "github.com/shylinux/icebergs" + "github.com/shylinux/icebergs/base/nfs" + "github.com/shylinux/icebergs/base/web" + kit "github.com/shylinux/toolkits" + + "path" +) + +const VIMER = "vimer" + +func init() { + Index.Merge(&ice.Context{ + Configs: map[string]*ice.Config{}, + Commands: map[string]*ice.Command{ + VIMER: {Name: "vimer path=usr/demo file=hi.sh line=1 刷新:button=auto 保存:button 运行:button 项目:button", Help: "编辑器", Meta: kit.Dict( + "display", "/plugin/local/code/vimer.js", "style", "editor", + ), Action: map[string]*ice.Action{ + web.UPLOAD: {Name: "upload path name", Help: "上传", Hand: func(m *ice.Message, arg ...string) { + m.Cmdy(web.CACHE, web.UPLOAD) + m.Cmdy(web.CACHE, web.WATCH, m.Option(web.DATA), path.Join(m.Option("path"), m.Option("name"))) + }}, + nfs.SAVE: {Name: "save type file path", Help: "保存", Hand: func(m *ice.Message, arg ...string) { + _vimer_save(m, arg[0], arg[1], arg[2], m.Option("content")) + }}, + + "cmd": {Name: "cmd type file path", Help: "命令", Hand: func(m *ice.Message, arg ...string) { + m.Cmdy(arg) + }}, + }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + m.Cmdy(INNER, arg) + }}, + }, + }, nil) +} diff --git a/core/code/qrcode.go b/core/wiki/qrcode.go similarity index 96% rename from core/code/qrcode.go rename to core/wiki/qrcode.go index 75a24209..436bcff7 100644 --- a/core/code/qrcode.go +++ b/core/wiki/qrcode.go @@ -1,4 +1,4 @@ -package code +package wiki import ( ice "github.com/shylinux/icebergs" @@ -6,6 +6,8 @@ import ( kit "github.com/shylinux/toolkits" ) +const QRCODE = "qrcode" + func init() { Index.Register(&ice.Context{Name: QRCODE, Help: "二维码", Configs: map[string]*ice.Config{ diff --git a/core/code/video.go b/core/wiki/video.go similarity index 95% rename from core/code/video.go rename to core/wiki/video.go index 9644bda2..a9bf75d0 100644 --- a/core/code/video.go +++ b/core/wiki/video.go @@ -1,4 +1,4 @@ -package code +package wiki import ( ice "github.com/shylinux/icebergs" @@ -15,7 +15,7 @@ func init() { Index.Register(&ice.Context{Name: "m4v", Help: "视频", Configs: map[string]*ice.Config{ - VEDIO: {Name: "vedio", Help: "视频", Value: kit.Data()}, + VIDEO: {Name: "video", Help: "视频", Value: kit.Data()}, }, Commands: map[string]*ice.Command{ "list": {Name: "list name", Help: "列表", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { diff --git a/core/wiki/word.go b/core/wiki/word.go index 444ca181..a2107822 100644 --- a/core/wiki/word.go +++ b/core/wiki/word.go @@ -85,8 +85,22 @@ func _refer_show(m *ice.Message, name, text string, arg ...string) { m.Render(ice.RENDER_TEMPLATE, m.Conf(REFER, "meta.template")) } func _spark_show(m *ice.Message, name, text string, arg ...string) { + switch text = strings.TrimSpace(text); name { + case "shell", "redis", "mysql": + m.Echo(`