forked from x/icebergs
add space
This commit is contained in:
parent
6df3a8144c
commit
1a404786d6
@ -6,7 +6,9 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
RSA = "rsa"
|
||||
RSA = "rsa"
|
||||
SIGN = "sign"
|
||||
VERIFY = "verify"
|
||||
)
|
||||
const AAA = "aaa"
|
||||
|
||||
|
@ -36,7 +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
|
||||
if !(dir_type == TYPE_CAT && isDir || dir_type == TYPE_DIR && !isDir) && (dir_reg == nil || dir_reg.MatchString(s.Name())) {
|
||||
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())) {
|
||||
switch cb := m.OptionCB("").(type) {
|
||||
case func(os.FileInfo, string):
|
||||
cb(s, p)
|
||||
@ -131,6 +132,7 @@ const (
|
||||
REQUIRE = "/require/"
|
||||
|
||||
TYPE_ALL = "all"
|
||||
TYPE_BIN = "bin"
|
||||
TYPE_CAT = "cat"
|
||||
TYPE_DIR = "dir"
|
||||
TYPE_BOTH = "both"
|
||||
|
@ -35,7 +35,7 @@ func init() {
|
||||
mdb.HashRemove(m, m.OptionSimple(mdb.HASH))
|
||||
}},
|
||||
mdb.CREATE: {Hand: func(m *ice.Message, arg ...string) {
|
||||
_trash_create(m, m.Option(FROM))
|
||||
_trash_create(m, kit.Paths(m.Option(FROM)))
|
||||
}},
|
||||
mdb.REMOVE: {Hand: func(m *ice.Message, arg ...string) {
|
||||
Remove(m, m.Option(FILE))
|
||||
@ -48,4 +48,4 @@ func init() {
|
||||
})
|
||||
}
|
||||
|
||||
func Trash(m *ice.Message, p string) *ice.Message { return m.Cmd(TRASH, mdb.CREATE, p) }
|
||||
func Trash(m *ice.Message, p string, arg ...string) *ice.Message { return m.Cmd(TRASH, mdb.CREATE, p) }
|
||||
|
@ -3,6 +3,7 @@ package web
|
||||
import (
|
||||
"os"
|
||||
"path"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
ice "shylinux.com/x/icebergs"
|
||||
@ -57,19 +58,29 @@ func _dream_show(m *ice.Message, name string) {
|
||||
), cli.CMD_OUTPUT, path.Join(p, ice.VAR_LOG_BOOT_LOG), mdb.CACHE_CLEAR_ONEXIT, ice.TRUE)
|
||||
defer m.Options(cli.CMD_DIR, "", cli.CMD_ENV, "", cli.CMD_OUTPUT, "")
|
||||
gdb.Event(m, DREAM_CREATE, m.OptionSimple(mdb.NAME, mdb.TYPE))
|
||||
kit.If(m.Option(nfs.TEMPLATE), func() { _dream_template(m, p) })
|
||||
kit.If(m.Option(nfs.BINARY), func(p string) { _dream_binary(m, p) })
|
||||
kit.If(m.Option(nfs.TEMPLATE), func(p string) { _dream_template(m, p) })
|
||||
m.Cmd(cli.DAEMON, kit.Select(kit.Path(os.Args[0]), cli.SystemFind(m, ice.ICE_BIN, nfs.PWD+path.Join(p, ice.BIN), nfs.PWD+ice.BIN)),
|
||||
SPACE, tcp.DIAL, ice.DEV, ice.OPS, mdb.TYPE, WORKER, m.OptionSimple(mdb.NAME), cli.DAEMON, ice.OPS)
|
||||
}
|
||||
func _dream_binary(m *ice.Message, p string) {
|
||||
if bin := path.Join(m.Option(cli.CMD_DIR), ice.BIN_ICE_BIN); kit.IsUrl(p) {
|
||||
SpideSave(m, bin, kit.MergeURL(p, cli.GOOS, runtime.GOOS, cli.GOARCH, runtime.GOARCH), nil)
|
||||
os.Chmod(bin, ice.MOD_DIR)
|
||||
} else {
|
||||
m.Cmd(nfs.LINK, bin, kit.Path(p))
|
||||
}
|
||||
}
|
||||
func _dream_template(m *ice.Message, p string) {
|
||||
kit.For([]string{ice.ETC_MISS_SH,
|
||||
kit.For([]string{
|
||||
ice.LICENSE, ice.MAKEFILE, ice.README_MD, ice.GO_MOD, ice.GO_SUM,
|
||||
ice.SRC_MAIN_GO, ice.SRC_MAIN_SH, ice.SRC_MAIN_SHY, ice.SRC_MAIN_JS,
|
||||
ice.SRC_MAIN_SH, ice.SRC_MAIN_SHY, ice.SRC_MAIN_GO, ice.SRC_MAIN_JS,
|
||||
ice.ETC_MISS_SH, ice.ETC_INIT_SHY, ice.ETC_EXIT_SHY,
|
||||
}, func(file string) {
|
||||
if nfs.Exists(m, path.Join(p, file)) {
|
||||
if nfs.Exists(m, kit.Path(m.Option(cli.CMD_DIR), file)) {
|
||||
return
|
||||
}
|
||||
switch m.Cmdy(nfs.COPY, path.Join(p, file), path.Join(ice.USR_LOCAL_WORK, m.Option(nfs.TEMPLATE), file)); file {
|
||||
switch m.Cmdy(nfs.COPY, kit.Path(m.Option(cli.CMD_DIR), file), kit.Path(ice.USR_LOCAL_WORK, p, file)); file {
|
||||
case ice.GO_MOD:
|
||||
nfs.Rewrite(m, path.Join(p, file), func(line string) string {
|
||||
return kit.Select(line, nfs.MODULE+lex.SP+m.Option(mdb.NAME), strings.HasPrefix(line, nfs.MODULE))
|
||||
@ -101,20 +112,16 @@ func init() {
|
||||
switch arg[0] {
|
||||
case mdb.NAME, nfs.TEMPLATE:
|
||||
_dream_list(m).Cut("name,status,time")
|
||||
case nfs.REPOS:
|
||||
if msg := m.Cmd(SPIDE, ice.OPS, SPIDE_MSG, UserHost(m)+"/x/list"); !msg.IsErr() {
|
||||
m.Copy(msg)
|
||||
}
|
||||
kit.For([]string{ice.OPS, ice.DEV, ice.SHY}, func(dev string) {
|
||||
if msg := m.Cmd(SPIDE, dev, SPIDE_MSG, "/x/list"); !msg.IsErr() {
|
||||
m.Copy(msg)
|
||||
}
|
||||
case nfs.BINARY:
|
||||
m.Cmdy(nfs.DIR, ice.BIN, "path,size,hashs,time", kit.Dict(nfs.DIR_TYPE, nfs.TYPE_BIN))
|
||||
m.Cmd(nfs.DIR, ice.USR_LOCAL_WORK, func(value ice.Maps) {
|
||||
m.Cmdy(nfs.DIR, path.Join(value[nfs.PATH], ice.BIN), "path,size,hashs,time", kit.Dict(nfs.DIR_TYPE, nfs.TYPE_BIN))
|
||||
})
|
||||
default:
|
||||
gdb.Event(m, "", arg)
|
||||
gdb.Event(m, DREAM_INPUTS, arg)
|
||||
}
|
||||
}},
|
||||
mdb.CREATE: {Name: "create name*=hi repos template", Hand: func(m *ice.Message, arg ...string) {
|
||||
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))))
|
||||
}},
|
||||
|
@ -27,8 +27,10 @@ func Render(m *ice.Message, cmd string, args ...ice.Any) bool {
|
||||
}
|
||||
arg := kit.Simple(args...)
|
||||
kit.If(len(arg) == 0, func() { args = nil })
|
||||
if cmd != "" && (cmd != ice.RENDER_DOWNLOAD || m.R.Method != http.MethodGet) {
|
||||
defer func() { m.Logs("Render", cmd, args) }()
|
||||
if cmd != "" {
|
||||
if cmd != ice.RENDER_DOWNLOAD || !kit.HasPrefix(arg[0], ice.USR_VOLCANOS, ice.USR_INTSHELL) {
|
||||
defer func() { m.Logs("Render", cmd, args) }()
|
||||
}
|
||||
}
|
||||
switch cmd {
|
||||
case COOKIE: // value [name [path [expire]]]
|
||||
|
@ -21,7 +21,9 @@ import (
|
||||
|
||||
func _serve_address(m *ice.Message) string { return Domain(tcp.LOCALHOST, m.Option(tcp.PORT)) }
|
||||
func _serve_start(m *ice.Message) {
|
||||
defer kit.For(kit.Split(m.Option(ice.DEV)), func(v string) { m.Sleep("10ms").Cmd(SPACE, tcp.DIAL, ice.DEV, v, mdb.NAME, ice.Info.NodeName) })
|
||||
defer kit.For(kit.Split(m.Option(ice.DEV)), func(v string) {
|
||||
m.Sleep("10ms").Cmd(SPACE, tcp.DIAL, ice.DEV, v, mdb.NAME, ice.Info.NodeName, TOKEN, m.Option(TOKEN))
|
||||
})
|
||||
kit.If(m.Option(aaa.USERNAME), func() { aaa.UserRoot(m, m.Option(aaa.USERNICK), m.Option(aaa.USERNAME)) })
|
||||
kit.If(m.Option(tcp.PORT) == tcp.RANDOM, func() { m.Option(tcp.PORT, m.Cmdx(tcp.PORT, aaa.RIGHT)) })
|
||||
kit.If(cli.IsWindows(), func() { m.Cmd(SPIDE, ice.OPS, _serve_address(m)+"/exit").Sleep30ms() })
|
||||
|
@ -19,6 +19,9 @@ import (
|
||||
)
|
||||
|
||||
func _share_link(m *ice.Message, p string, arg ...ice.Any) string {
|
||||
if strings.HasPrefix(p, ice.USR_PUBLISH) {
|
||||
return tcp.PublishLocalhost(m, MergeLink(m, strings.TrimPrefix(p, ice.USR), arg...))
|
||||
}
|
||||
return tcp.PublishLocalhost(m, MergeLink(m, kit.Select("", PP(SHARE, LOCAL), !strings.HasPrefix(p, nfs.PS) && !strings.HasPrefix(p, HTTP))+p, arg...))
|
||||
}
|
||||
func _share_cache(m *ice.Message, arg ...string) {
|
||||
@ -129,6 +132,9 @@ func ShareLocalFile(m *ice.Message, arg ...string) {
|
||||
if m.Option(ice.POD) == "" {
|
||||
m.RenderDownload(p)
|
||||
return
|
||||
} else if p := kit.Path(ice.USR_LOCAL_WORK, m.Option(ice.POD), p); nfs.Exists(m, p) {
|
||||
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)
|
||||
|
@ -48,11 +48,18 @@ func _space_dial(m *ice.Message, dev, name string, arg ...string) {
|
||||
func _space_fork(m *ice.Message) {
|
||||
addr := kit.Select(m.R.RemoteAddr, m.R.Header.Get(ice.MSG_USERADDR))
|
||||
name := kit.ReplaceAll(kit.Select(addr, m.Option(mdb.NAME)), "[", "_", "]", "_", nfs.DF, "_", nfs.PT, "_")
|
||||
args := kit.Simple(mdb.TYPE, kit.Select(WORKER, m.Option(mdb.TYPE)), mdb.NAME, name, mdb.TEXT, kit.Select(addr, m.Option(mdb.TEXT)), m.OptionSimple(cli.DAEMON, ice.MSG_USERUA))
|
||||
text := kit.Select(addr, m.Option(mdb.TEXT))
|
||||
if kit.IsIn(m.Option(mdb.TYPE), CHROME) || !(ice.Info.Localhost && tcp.IsLocalHost(m, strings.Split(m.R.RemoteAddr, nfs.DF)[0]) ||
|
||||
m.Option(TOKEN) != "" && m.Cmdv(TOKEN, m.Option(TOKEN), mdb.TIME) > m.Time()) {
|
||||
name = kit.ReplaceAll(addr, "[", "_", "]", "_", nfs.DF, "_", nfs.PT, "_")
|
||||
text = kit.Select(addr, m.Option(mdb.NAME), m.Option(mdb.TEXT))
|
||||
}
|
||||
args := kit.Simple(mdb.TYPE, kit.Select(WORKER, m.Option(mdb.TYPE)), mdb.NAME, name, mdb.TEXT, text, m.OptionSimple(cli.DAEMON, ice.MSG_USERUA))
|
||||
if c, e := websocket.Upgrade(m.W, m.R); !m.Warn(e) {
|
||||
gdb.Go(m, func() {
|
||||
defer mdb.HashCreateDeferRemove(m, args, kit.Dict(mdb.TARGET, c))()
|
||||
switch m.Option(mdb.TYPE) {
|
||||
case SERVER:
|
||||
case WORKER:
|
||||
defer gdb.EventDeferEvent(m, DREAM_OPEN, args)(DREAM_CLOSE, args)
|
||||
case CHROME:
|
||||
@ -115,7 +122,11 @@ func _space_exec(m *ice.Message, source, target []string, c *websocket.Conn) {
|
||||
case cli.PWD:
|
||||
m.Push(mdb.LINK, m.MergePod(kit.Select("", source, -1)))
|
||||
default:
|
||||
kit.If(aaa.Right(m, m.Detailv()), func() { m = m.Cmd() })
|
||||
kit.If(aaa.Right(m, m.Detailv()), func() {
|
||||
m.TryCatch(m, true, func(_ *ice.Message) {
|
||||
m = m.Cmd()
|
||||
})
|
||||
})
|
||||
}
|
||||
defer m.Cost(kit.Format("%v->%v %v %v", source, target, m.Detailv(), m.FormatSize()))
|
||||
_space_echo(m.Set(ice.MSG_OPTS).Options(log.DEBUG, m.Option(log.DEBUG)), []string{}, kit.Reverse(kit.Simple(source)), c)
|
||||
|
@ -54,11 +54,11 @@ func _spide_show(m *ice.Message, name string, arg ...string) {
|
||||
}
|
||||
defer res.Body.Close()
|
||||
m.Cost(cli.STATUS, res.Status, nfs.SIZE, res.Header.Get(ContentLength), mdb.TYPE, res.Header.Get(ContentType))
|
||||
kit.For(res.Header, func(k string, v []string) { m.Logs(mdb.IMPORT, k, v) })
|
||||
kit.For(res.Header, func(k string, v []string) { m.Logs("response", k, v) })
|
||||
mdb.HashSelectUpdate(m, name, func(value ice.Map) {
|
||||
kit.For(res.Cookies(), func(v *http.Cookie) {
|
||||
kit.Value(value, kit.Keys(SPIDE_COOKIE, v.Name), v.Value)
|
||||
m.Logs(mdb.IMPORT, v.Name, v.Value)
|
||||
m.Logs("response", v.Name, v.Value)
|
||||
})
|
||||
})
|
||||
if m.Warn(res.StatusCode != http.StatusOK, ice.ErrNotValid, uri, cli.STATUS, res.Status) {
|
||||
|
19
base/web/token.go
Normal file
19
base/web/token.go
Normal file
@ -0,0 +1,19 @@
|
||||
package web
|
||||
|
||||
import (
|
||||
ice "shylinux.com/x/icebergs"
|
||||
"shylinux.com/x/icebergs/base/mdb"
|
||||
kit "shylinux.com/x/toolkits"
|
||||
)
|
||||
|
||||
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) {
|
||||
if mdb.HashSelect(m, arg...); len(arg) > 0 {
|
||||
m.Cmdy("web.code.publish", ice.CONTEXTS, kit.Dict(TOKEN, arg[0]))
|
||||
}
|
||||
}},
|
||||
})
|
||||
}
|
@ -104,7 +104,7 @@ func init() {
|
||||
m.Option(mdb.TYPE, mdb.HashSelects(m.Spawn(), m.Option(mdb.HASH)).Append(mdb.TYPE))
|
||||
ctx.Run(m, arg...)
|
||||
}},
|
||||
}, ctx.CmdAction(), mdb.HashAction(), mdb.ImportantDataAction(), KeyboardAction()), Hand: func(m *ice.Message, arg ...string) {
|
||||
}, ctx.CmdAction(), mdb.HashAction(), mdb.ImportantDataAction()), Hand: func(m *ice.Message, arg ...string) {
|
||||
if len(arg) > 0 && arg[0] == ctx.ACTION {
|
||||
m.Option(mdb.TYPE, mdb.HashSelects(m.Spawn(), m.Option(mdb.HASH)).Append(mdb.TYPE))
|
||||
gdb.Event(m, FAVOR_ACTION, arg)
|
||||
|
@ -2,6 +2,7 @@ package chat
|
||||
|
||||
import (
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
ice "shylinux.com/x/icebergs"
|
||||
"shylinux.com/x/icebergs/base/aaa"
|
||||
@ -18,12 +19,12 @@ const POD = "pod"
|
||||
func init() {
|
||||
Index.MergeCommands(ice.Commands{
|
||||
POD: {Name: "pod", Help: "节点", Actions: ice.MergeActions(ctx.CmdAction(), web.ApiAction(), aaa.WhiteAction()), Hand: func(m *ice.Message, arg ...string) {
|
||||
if web.AgentIs(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
|
||||
}
|
||||
if len(arg) == 0 || kit.Select("", arg, 0) == "" {
|
||||
web.RenderCmd(m, web.SPACE)
|
||||
} else if strings.HasPrefix(m.Option(ice.MSG_USERUA), "git/") {
|
||||
m.RenderRedirect(m.Cmdv(web.SPACE, arg[0], "web.code.git.repos", nfs.REMOTE, nfs.REMOTE) + "/info/refs?service=" + m.Option("service"))
|
||||
} else if m.Option(cli.GOOS) != "" && m.Option(cli.GOARCH) != "" {
|
||||
m.RenderDownload(path.Join(ice.USR_LOCAL_WORK, arg[0], ice.USR_PUBLISH, kit.Keys(ice.ICE, m.Option(cli.GOOS), m.Option(cli.GOARCH))))
|
||||
} else if len(arg) == 1 {
|
||||
if m.Cmd(web.SPACE, arg[0]).Length() == 0 && nfs.Exists(m, path.Join(ice.USR_LOCAL_WORK, arg[0])) {
|
||||
m.Cmd(web.DREAM, cli.START, kit.Dict(mdb.NAME, arg[0]))
|
||||
|
@ -53,7 +53,7 @@ func _autogen_import(m *ice.Message, main string, ctx string, mod string) {
|
||||
}
|
||||
func _autogen_version(m *ice.Message) string {
|
||||
if mod := _autogen_mod(m, ice.GO_MOD); !nfs.Exists(m, ".git") {
|
||||
m.Cmd(REPOS, "init", nfs.ORIGIN, kit.Select(m.Option(ice.MSG_USERHOST), ice.Info.Make.Domain)+"/x/"+path.Base(mod), mdb.NAME, path.Base(mod), nfs.PATH, nfs.PWD)
|
||||
m.Cmd(REPOS, "init", nfs.ORIGIN, strings.Split(kit.MergeURL2(kit.Select(ice.Info.Make.Remote, ice.Info.Make.Domain), "/x/"+path.Base(mod)), mdb.QS)[0], mdb.NAME, path.Base(mod), nfs.PATH, nfs.PWD)
|
||||
defer m.Cmd(REPOS, "add", kit.Dict(nfs.REPOS, path.Base(mod), nfs.FILE, nfs.SRC))
|
||||
defer m.Cmd(REPOS, "add", kit.Dict(nfs.REPOS, path.Base(mod), nfs.FILE, "go.mod"))
|
||||
}
|
||||
@ -74,14 +74,11 @@ func _autogen_gits(m *ice.Message, arg ...string) string {
|
||||
return kit.Join(res, lex.NL)
|
||||
}
|
||||
func _autogen_git(m *ice.Message, arg ...string) ice.Map {
|
||||
msg := m.Cmd("web.code.git.repos", "remote")
|
||||
return kit.Dict(arg,
|
||||
mdb.TIME, m.Time(), nfs.PATH, kit.Path(""), web.DOMAIN, web.UserHost(m),
|
||||
mdb.HASH, m.Cmdx(cli.SYSTEM, GIT, "log", "-n1", `--pretty=%H`),
|
||||
nfs.REMOTE, m.Cmdx(cli.SYSTEM, GIT, "config", "remote.origin.url"),
|
||||
nfs.BRANCH, m.Cmdx(cli.SYSTEM, GIT, "rev-parse", "--abbrev-ref", "HEAD"),
|
||||
nfs.VERSION, m.Cmdx(cli.SYSTEM, GIT, "describe", "--tags"),
|
||||
aaa.EMAIL, m.Cmdx(cli.SYSTEM, GIT, "config", "user.email"),
|
||||
aaa.USERNAME, kit.Select(ice.Info.Username, m.Cmdx(cli.SYSTEM, GIT, "config", "user.name")),
|
||||
mdb.TIME, m.Time(), nfs.PATH, kit.Path(""), web.DOMAIN, tcp.PublishLocalhost(m, m.Option(ice.MSG_USERWEB)),
|
||||
mdb.HASH, msg.Append(mdb.HASH), nfs.REMOTE, msg.Append(nfs.REMOTE), nfs.BRANCH, msg.Append(nfs.BRANCH), nfs.VERSION, msg.Append(nfs.VERSION),
|
||||
aaa.EMAIL, msg.Append(aaa.EMAIL), aaa.USERNAME, msg.Append(aaa.USERNAME),
|
||||
)
|
||||
}
|
||||
func _autogen_mod(m *ice.Message, file string) (mod string) {
|
||||
|
@ -118,7 +118,6 @@ func init() {
|
||||
ProcessXterm(m, cmds, text, arg[1])
|
||||
}},
|
||||
mdb.ENGINE: {Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmd(yac.STACK, kit.Simple(path.Join(arg[2], arg[1])))
|
||||
if cmd := ctx.GetFileCmd(path.Join(arg[2], arg[1])); cmd != "" {
|
||||
ctx.ProcessCommand(m, cmd, kit.Simple())
|
||||
return
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
|
||||
ice "shylinux.com/x/icebergs"
|
||||
"shylinux.com/x/icebergs/base/cli"
|
||||
"shylinux.com/x/icebergs/base/ctx"
|
||||
"shylinux.com/x/icebergs/base/mdb"
|
||||
"shylinux.com/x/icebergs/base/nfs"
|
||||
"shylinux.com/x/icebergs/base/web"
|
||||
@ -21,28 +22,33 @@ func init() {
|
||||
nfs.TARGET, kit.Dict(mdb.LIST, kit.List(mdb.TYPE, ice.BIN, nfs.FILE, ice.ICE_BIN)),
|
||||
nfs.BINARY, kit.Dict(mdb.LIST, kit.List(mdb.TYPE, nfs.TAR, nfs.FILE, "contexts.bin.tar.gz")),
|
||||
nfs.SOURCE, kit.Dict(mdb.LIST, kit.List(mdb.TYPE, nfs.TAR, nfs.FILE, "contexts.src.tar.gz")),
|
||||
ctx.CONFIG, kit.Dict(mdb.LIST, kit.List(mdb.TYPE, nfs.SHY, nfs.FILE, ice.ETC_LOCAL_SHY)),
|
||||
COMPILE, kit.Dict(mdb.LIST, kit.List(mdb.TYPE, nfs.TAR, nfs.FILE, "go1.15.5", nfs.PATH, ice.USR_LOCAL)),
|
||||
), mdb.META, kit.Dict(mdb.FIELD, "type,file,path"))},
|
||||
}, Commands: ice.Commands{
|
||||
UPGRADE: {Name: "upgrade item=target,binary,source,compile run restart", Help: "升级", Actions: ice.MergeActions(ice.Actions{
|
||||
UPGRADE: {Name: "upgrade item=target,config,binary,source,compile run restart", Help: "升级", Actions: ice.MergeActions(ice.Actions{
|
||||
cli.RESTART: {Hand: func(m *ice.Message, arg ...string) { m.Go(func() { m.Sleep300ms(ice.EXIT, 1) }) }},
|
||||
}), Hand: func(m *ice.Message, arg ...string) {
|
||||
mdb.ZoneSelect(m.Spawn(), kit.Select(nfs.TARGET, arg, 0)).Table(func(value ice.Maps) {
|
||||
if value[nfs.FILE] == ice.ICE_BIN {
|
||||
if kit.Select("", arg, 0) == COMPILE {
|
||||
value[nfs.FILE] = kit.Keys(kit.Format(value[nfs.FILE]), runtime.GOOS+"-"+runtime.GOARCH, kit.Select("tar.gz", "zip", runtime.GOOS == cli.WINDOWS))
|
||||
}
|
||||
if value[nfs.FILE] == ice.ICE_BIN && os.Getenv(cli.CTX_POD) == "" {
|
||||
value[nfs.FILE] = kit.Keys(ice.ICE, runtime.GOOS, runtime.GOARCH)
|
||||
defer nfs.Rename(m, value[nfs.FILE], ice.BIN_ICE_BIN)
|
||||
m.Option(ice.EXIT, ice.TRUE)
|
||||
}
|
||||
if kit.Select("", arg, 0) == COMPILE {
|
||||
value[nfs.FILE] = kit.Keys(kit.Format(value[nfs.FILE]), runtime.GOOS+"-"+runtime.GOARCH, kit.Select("tar.gz", "zip", runtime.GOOS == cli.WINDOWS))
|
||||
uri := "/publish/" + kit.Format(value[nfs.FILE])
|
||||
if os.Getenv(cli.CTX_POD) != "" {
|
||||
uri = kit.MergeURL2(os.Getenv(cli.CTX_DEV), "/chat/pod/"+os.Getenv(cli.CTX_POD), cli.GOOS, runtime.GOOS, cli.GOARCH, runtime.GOARCH)
|
||||
}
|
||||
dir := path.Join(kit.Format(value[nfs.PATH]), kit.Format(value[nfs.FILE]))
|
||||
switch web.SpideSave(m, dir, "/publish/"+kit.Format(value[nfs.FILE]), nil); value[mdb.TYPE] {
|
||||
switch web.SpideSave(m, dir, uri, nil); value[mdb.TYPE] {
|
||||
case nfs.TAR:
|
||||
m.Cmd(cli.SYSTEM, nfs.TAR, "xf", dir, "-C", path.Dir(dir))
|
||||
// m.Cmd(nfs.TAR, mdb.EXPORT, dir, "-C", path.Dir(dir))
|
||||
case ice.BIN:
|
||||
os.Chmod(dir, 0755)
|
||||
os.Chmod(dir, ice.MOD_DIR)
|
||||
}
|
||||
m.Cmdy(nfs.DIR, dir, "time,size,path,hash")
|
||||
})
|
||||
|
2
exec.go
2
exec.go
@ -83,7 +83,7 @@ func (m *Message) Cmdv(arg ...Any) string {
|
||||
}
|
||||
func (m *Message) Cmdx(arg ...Any) string {
|
||||
res := strings.TrimSpace(kit.Select("", m._command(arg...).meta[MSG_RESULT], 0))
|
||||
return kit.Select("", res, res != ErrWarn)
|
||||
return kit.Select("", res, res != strings.TrimSpace(ErrWarn))
|
||||
}
|
||||
func (m *Message) Cmdy(arg ...Any) *Message { return m.Copy(m._command(arg...)) }
|
||||
func (m *Message) CmdHand(cmd *Command, key string, arg ...string) *Message {
|
||||
|
7
info.go
7
info.go
@ -105,6 +105,7 @@ func MergeActions(arg ...Any) Actions {
|
||||
h = list[CTX_INIT]
|
||||
}
|
||||
h.Hand = MergeHand(h.Hand, func(m *Message, arg ...string) {
|
||||
_cmd := m._cmd
|
||||
m.Search(from, func(p *Context, s *Context, key string, cmd *Command) {
|
||||
for k, v := range cmd.Actions {
|
||||
func(k string) {
|
||||
@ -113,6 +114,12 @@ func MergeActions(arg ...Any) Actions {
|
||||
} else if h.Hand == nil {
|
||||
h.Hand = func(m *Message, arg ...string) { m.Cmdy(from, k, arg) }
|
||||
}
|
||||
if help := kit.Split(v.Help, " ::"); len(help) > 0 {
|
||||
if kit.Value(_cmd.Meta, kit.Keys("_trans", strings.TrimPrefix(k, "_")), help[0]); len(help) > 1 {
|
||||
kit.Value(_cmd.Meta, kit.Keys("_title", k), help[1])
|
||||
}
|
||||
}
|
||||
kit.If(len(v.List) > 0, func() { _cmd.Meta[k] = v.List })
|
||||
}(k)
|
||||
}
|
||||
})
|
||||
|
@ -18,6 +18,7 @@ import (
|
||||
"shylinux.com/x/icebergs/base/aaa"
|
||||
"shylinux.com/x/icebergs/base/cli"
|
||||
"shylinux.com/x/icebergs/base/ctx"
|
||||
"shylinux.com/x/icebergs/base/gdb"
|
||||
"shylinux.com/x/icebergs/base/lex"
|
||||
"shylinux.com/x/icebergs/base/log"
|
||||
"shylinux.com/x/icebergs/base/mdb"
|
||||
@ -347,6 +348,17 @@ func init() {
|
||||
m.PushSearch(mdb.TYPE, web.LINK, mdb.NAME, m.CommandKey(), mdb.TEXT, m.MergePodCmd("", "", log.DEBUG, ice.TRUE))
|
||||
}
|
||||
}},
|
||||
mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) {
|
||||
switch arg[0] {
|
||||
case COMMENT:
|
||||
ls := kit.Split(m.Option(nfs.FILE), " /")
|
||||
m.Push(arg[0], kit.Join(kit.Slice(ls, -1), nfs.PS))
|
||||
m.Push(arg[0], kit.Join(kit.Slice(ls, -2), nfs.PS))
|
||||
m.Push(arg[0], m.Option(nfs.FILE))
|
||||
case VERSION:
|
||||
m.Push(VERSION, _status_tag(m, m.Option(TAGS)))
|
||||
}
|
||||
}},
|
||||
INIT: {Name: "clone origin* branch name path", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmd(nfs.DEFS, kit.Path(".git/config"), nfs.Template(m, "config", m.Option("origin")))
|
||||
git.PlainInit(m.Option(nfs.PATH), false)
|
||||
@ -359,7 +371,7 @@ func init() {
|
||||
_repos_insert(m, m.Option(nfs.PATH))
|
||||
}
|
||||
}},
|
||||
PULL: {Hand: func(m *ice.Message, arg ...string) {
|
||||
PULL: {Help: "下载", Hand: func(m *ice.Message, arg ...string) {
|
||||
_repos_each(m, "", func(repos *git.Repository, value ice.Maps) error {
|
||||
if value[ORIGIN] == "" {
|
||||
return nil
|
||||
@ -370,14 +382,15 @@ func init() {
|
||||
}
|
||||
})
|
||||
}},
|
||||
PUSH: {Hand: func(m *ice.Message, arg ...string) {
|
||||
PUSH: {Help: "上传", Hand: func(m *ice.Message, arg ...string) {
|
||||
list := _repos_credentials(m)
|
||||
_repos_each(m, "", func(repos *git.Repository, value ice.Maps) error {
|
||||
if value[ORIGIN] == "" {
|
||||
return nil
|
||||
}
|
||||
u := list[kit.ParseURL(value[ORIGIN]).Host]
|
||||
if password, ok := u.User.Password(); !ok {
|
||||
if u, ok := list[kit.ParseURL(value[ORIGIN]).Host]; !ok {
|
||||
return errors.New("not found userinfo")
|
||||
} else if password, ok := u.User.Password(); !ok {
|
||||
return errors.New("not found password")
|
||||
} else {
|
||||
return repos.Push(&git.PushOptions{Auth: &http.BasicAuth{Username: u.User.Username(), Password: password}})
|
||||
@ -405,7 +418,7 @@ func init() {
|
||||
}
|
||||
}},
|
||||
STASH: {Hand: func(m *ice.Message, arg ...string) { _repos_cmd(m, kit.Select(m.Option(REPOS), arg, 0), STASH) }},
|
||||
COMMIT: {Name: "commit actions=add,opt,fix comment*=some", Hand: func(m *ice.Message, arg ...string) {
|
||||
COMMIT: {Name: "commit actions=add,opt,fix comment*=some", Help: "提交", Hand: func(m *ice.Message, arg ...string) {
|
||||
if work, err := _repos_open(m, m.Option(REPOS)).Worktree(); !m.Warn(err) {
|
||||
opt := &git.CommitOptions{All: true}
|
||||
if cfg, err := config.LoadConfig(config.GlobalScope); err == nil {
|
||||
@ -444,6 +457,25 @@ func init() {
|
||||
m.Sort("repos,status,file").Status(mdb.TIME, last, kit.Select(aaa.TECH, aaa.VOID, password == ""), m.Option(aaa.EMAIL), REMOTE, remote, kit.MDB_COUNT, kit.Split(m.FormatSize())[0], kit.MDB_COST, m.FormatCost())
|
||||
}
|
||||
}},
|
||||
REMOTE: {Hand: func(m *ice.Message, arg ...string) {
|
||||
repos := _repos_open(m, kit.Select(path.Base(kit.Path("")), kit.Select(m.Option(REPOS), arg, 0)))
|
||||
if _remote, err := repos.Remote(ORIGIN); err == nil {
|
||||
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(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/"))
|
||||
}
|
||||
}
|
||||
if cfg, err := config.LoadConfig(config.GlobalScope); err == nil {
|
||||
m.Push(aaa.EMAIL, kit.Select(m.Option(ice.MSG_USERNAME)+"@163.com", cfg.User.Email))
|
||||
m.Push(aaa.USERNAME, kit.Select(m.Option(ice.MSG_USERNAME), cfg.User.Name))
|
||||
}
|
||||
}},
|
||||
TOTAL: {Hand: func(m *ice.Message, arg ...string) {
|
||||
stats := map[string]int{}
|
||||
if repos := kit.Select(m.Option(REPOS), arg, 0); repos == "" {
|
||||
@ -482,11 +514,13 @@ func init() {
|
||||
}},
|
||||
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]
|
||||
kit.If(!strings.Contains(p, "://"), func() { p = web.UserHost(m) + "/x/" + p })
|
||||
m.Cmd("", CLONE, ORIGIN, p, nfs.PATH, m.Option(cli.CMD_DIR), ice.Maps{cli.CMD_DIR: ""})
|
||||
})
|
||||
}},
|
||||
code.INNER: {Hand: func(m *ice.Message, arg ...string) { _repos_inner(m, _repos_path, arg...) }},
|
||||
}, 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), mdb.HashAction(mdb.SHORT, REPOS, mdb.FIELD, "time,repos,branch,commit,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 {
|
||||
|
@ -15,6 +15,7 @@ import (
|
||||
ice "shylinux.com/x/icebergs"
|
||||
"shylinux.com/x/icebergs/base/aaa"
|
||||
"shylinux.com/x/icebergs/base/cli"
|
||||
"shylinux.com/x/icebergs/base/gdb"
|
||||
"shylinux.com/x/icebergs/base/lex"
|
||||
"shylinux.com/x/icebergs/base/mdb"
|
||||
"shylinux.com/x/icebergs/base/nfs"
|
||||
@ -113,7 +114,7 @@ func init() {
|
||||
m.Warn(_service_repos(m, arg...), ice.ErrNotValid)
|
||||
}}})
|
||||
Index.MergeCommands(ice.Commands{
|
||||
SERVICE: {Name: "service repos commit file auto", Help: "代码源", Actions: ice.MergeActions(ice.Actions{
|
||||
SERVICE: {Name: "service repos branch commit file auto", Help: "代码源", Actions: ice.MergeActions(ice.Actions{
|
||||
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmd(nfs.DIR, ice.USR_LOCAL_REPOS, func(value ice.Maps) { _repos_insert(m, value[nfs.PATH]) })
|
||||
}},
|
||||
@ -140,20 +141,29 @@ func init() {
|
||||
}},
|
||||
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...) }},
|
||||
}, mdb.HashAction(mdb.SHORT, REPOS, mdb.FIELD, "time,repos,branch,commit"), mdb.ClearOnExitHashAction()), Hand: func(m *ice.Message, arg ...string) {
|
||||
web.DREAM_INPUTS: {Hand: func(m *ice.Message, arg ...string) {
|
||||
switch arg[0] {
|
||||
case REPOS:
|
||||
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) {
|
||||
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"))
|
||||
} 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)
|
||||
}
|
||||
} else if len(arg) == 2 {
|
||||
if repos := _repos_open(m, arg[0]); arg[1] == INDEX {
|
||||
} else if len(arg) == 3 {
|
||||
if repos := _repos_open(m, arg[0]); arg[2] == INDEX {
|
||||
_repos_status(m, arg[0], repos)
|
||||
} else {
|
||||
_repos_stats(m, repos, arg[1])
|
||||
_repos_stats(m, repos, arg[2])
|
||||
}
|
||||
} else {
|
||||
m.Cmdy("", code.INNER, arg)
|
||||
|
@ -116,38 +116,27 @@ func init() {
|
||||
return
|
||||
}
|
||||
switch arg[0] {
|
||||
case COMMENT:
|
||||
ls := kit.Split(m.Option(nfs.FILE), " /")
|
||||
m.Push(arg[0], kit.Join(kit.Slice(ls, -1), nfs.PS))
|
||||
m.Push(arg[0], kit.Join(kit.Slice(ls, -2), nfs.PS))
|
||||
m.Push(arg[0], m.Option(nfs.FILE))
|
||||
case VERSION:
|
||||
m.Push(VERSION, _status_tag(m, m.Option(TAGS)))
|
||||
case aaa.EMAIL:
|
||||
m.Push(arg[0], _configs_get(m, USER_EMAIL), ice.Info.Make.Email)
|
||||
case aaa.USERNAME:
|
||||
m.Push(arg[0], kit.Select(m.Option(ice.MSG_USERNAME), _configs_get(m, USER_NAME)), ice.Info.Make.Username)
|
||||
default:
|
||||
m.Cmdy(REPOS, mdb.INPUTS, arg)
|
||||
}
|
||||
}},
|
||||
CONFIGS: {Name: "configs email username", Help: "配置", Hand: func(m *ice.Message, arg ...string) {
|
||||
mdb.Config(m, aaa.USERNAME, m.Option(aaa.USERNAME))
|
||||
mdb.Config(m, aaa.EMAIL, m.Option(aaa.EMAIL))
|
||||
}},
|
||||
INSTEADOF: {Name: "insteadof from* to", Help: "代理", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmd(CONFIGS, func(value ice.Maps) {
|
||||
kit.If(value[mdb.VALUE] == m.Option(nfs.FROM), func() { _configs_set(m, "--unset", value[mdb.NAME]) })
|
||||
})
|
||||
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) {
|
||||
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)))
|
||||
}},
|
||||
TAG: {Name: "tag version", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmdy(REPOS, m.ActionKey(), arg)
|
||||
}},
|
||||
COMMIT: {Name: "commit actions=add,opt,fix comment*=some", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmdy(REPOS, m.ActionKey(), arg)
|
||||
}},
|
||||
web.DREAM_TABLES: {Hand: func(m *ice.Message, arg ...string) {
|
||||
if m.Option(mdb.TYPE) != web.WORKER {
|
||||
return
|
||||
@ -164,7 +153,7 @@ func init() {
|
||||
}
|
||||
m.Push(mdb.TEXT, strings.Join(text, ", "))
|
||||
}},
|
||||
}, gdb.EventAction(web.DREAM_TABLES), aaa.RoleAction(), mdb.ImportantDataAction()), Hand: func(m *ice.Message, arg ...string) {
|
||||
}, gdb.EventAction(web.DREAM_TABLES), Prefix(REPOS), mdb.ImportantDataAction(), aaa.RoleAction()), 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) == "" {
|
||||
|
@ -1,9 +1,12 @@
|
||||
package ssh
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/sha256"
|
||||
"crypto/x509"
|
||||
"encoding/hex"
|
||||
"encoding/pem"
|
||||
"path"
|
||||
|
||||
@ -20,6 +23,8 @@ import (
|
||||
const (
|
||||
PUBLIC = "public"
|
||||
PRIVATE = "private"
|
||||
VERIFY = "verify"
|
||||
SIGN = "sign"
|
||||
)
|
||||
const RSA = "rsa"
|
||||
|
||||
@ -60,6 +65,46 @@ func init() {
|
||||
PUBLIC, m.Cmdx(nfs.CAT, kit.HomePath(m.Option(PUB))),
|
||||
))
|
||||
}},
|
||||
SIGN: {Hand: func(m *ice.Message, arg ...string) {
|
||||
if !nfs.Exists(m, "etc/id_rsa") {
|
||||
if key, err := rsa.GenerateKey(rand.Reader, kit.Int("2048")); !m.Warn(err, ice.ErrNotValid) {
|
||||
m.Cmd(nfs.SAVE, "etc/id_rsa", string(pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(key)})))
|
||||
m.Cmd(nfs.SAVE, "etc/id_rsa.pub", string(pem.EncodeToMemory(&pem.Block{Type: "RSA PUBLIC KEY", Bytes: x509.MarshalPKCS1PublicKey(key.Public().(*rsa.PublicKey))})))
|
||||
}
|
||||
}
|
||||
block, _ := pem.Decode([]byte(m.Cmdx(nfs.CAT, "etc/id_rsa")))
|
||||
key, err := x509.ParsePKCS1PrivateKey(block.Bytes)
|
||||
if m.Warn(err) {
|
||||
return
|
||||
}
|
||||
hash := sha256.New()
|
||||
if _, err := hash.Write([]byte(arg[0])); m.Warn(err) {
|
||||
return
|
||||
}
|
||||
signature, err := rsa.SignPSS(rand.Reader, key, crypto.SHA256, hash.Sum(nil), nil)
|
||||
if m.Warn(err) {
|
||||
return
|
||||
}
|
||||
m.Echo(hex.EncodeToString(signature))
|
||||
}},
|
||||
VERIFY: {Hand: func(m *ice.Message, arg ...string) {
|
||||
block, _ := pem.Decode([]byte(m.Cmdx(nfs.CAT, "etc/id_rsa.pub")))
|
||||
pub, err := x509.ParsePKCS1PublicKey(block.Bytes)
|
||||
if m.Warn(err) {
|
||||
return
|
||||
}
|
||||
signature, err := hex.DecodeString(arg[1])
|
||||
if m.Warn(err) {
|
||||
return
|
||||
}
|
||||
hash := sha256.New()
|
||||
if _, err := hash.Write([]byte(arg[0])); m.Warn(err) {
|
||||
return
|
||||
}
|
||||
if !m.Warn(rsa.VerifyPSS(pub, crypto.SHA256, hash.Sum(nil), signature, nil)) {
|
||||
m.Echo(ice.OK)
|
||||
}
|
||||
}},
|
||||
}, mdb.HashAction(mdb.SHORT, PRIVATE, mdb.FIELD, "time,hash,title,public,private")), Hand: func(m *ice.Message, arg ...string) {
|
||||
if mdb.HashSelect(m, arg...).PushAction(mdb.EXPORT, mdb.REMOVE); len(arg) == 0 {
|
||||
m.Action(mdb.CREATE, mdb.IMPORT)
|
||||
|
Loading…
x
Reference in New Issue
Block a user