diff --git a/base/cli/daemon.go b/base/cli/daemon.go index a4997a17..83da1467 100644 --- a/base/cli/daemon.go +++ b/base/cli/daemon.go @@ -52,7 +52,7 @@ func _daemon_exec(m *ice.Message, cmd *exec.Cmd) { m.ErrorNotImplement(cb) } for _, p := range kit.Simple(CMD_INPUT, CMD_OUTPUT, CMD_ERRPUT) { - nfs.CloseFile(m, m.Optionv(p)) + nfs.Close(m, m.Optionv(p)) } }) } diff --git a/base/cli/forever.go b/base/cli/forever.go index e7e8aa5c..87a39a51 100644 --- a/base/cli/forever.go +++ b/base/cli/forever.go @@ -43,7 +43,7 @@ func init() { m.Options(CMD_ENV, env, CMD_INPUT, os.Stdin, CMD_OUTPUT, os.Stdout, CMD_ERRPUT, os.Stderr) kit.If(kit.Env(CTX_LOG), func(p string) { m.Optionv(CMD_ERRPUT, p) }) m.Cmd(FOREVER, STOP) - if bin := kit.Select(os.Args[0], ice.BIN_ICE_BIN, nfs.ExistsFile(m, ice.BIN_ICE_BIN)); len(arg) > 0 && arg[0] == ice.SPACE { + if bin := kit.Select(os.Args[0], ice.BIN_ICE_BIN, nfs.Exists(m, ice.BIN_ICE_BIN)); len(arg) > 0 && arg[0] == ice.SPACE { m.Cmdy(FOREVER, bin, ice.SPACE, START, ice.DEV, ice.OPS, arg[1:]) } else { kit.If(len(arg) == 0 || arg[0] != ice.DEV, func() { arg = append([]string{ice.DEV, ""}, arg...) }) diff --git a/base/cli/system.go b/base/cli/system.go index a18c09b8..98ec95a2 100644 --- a/base/cli/system.go +++ b/base/cli/system.go @@ -55,7 +55,7 @@ func _system_cmd(m *ice.Message, arg ...string) *exec.Cmd { } cmd := exec.Command(kit.Select(arg[0], bin), arg[1:]...) if cmd.Dir = kit.TrimPath(m.Option(CMD_DIR)); len(cmd.Dir) > 0 { - if m.Logs(EXEC, CMD_DIR, cmd.Dir); !nfs.ExistsFile(m, cmd.Dir) { + if m.Logs(EXEC, CMD_DIR, cmd.Dir); !nfs.Exists(m, cmd.Dir) { file.MkdirAll(cmd.Dir, ice.MOD_DIR) } } @@ -117,14 +117,14 @@ func _system_find(m Message, bin string, dir ...string) string { } kit.If(len(dir) == 0, func() { dir = append(dir, _path_split(kit.Env(PATH))...) }) for _, p := range dir { - if nfs.ExistsFile(m, path.Join(p, bin)) { + if nfs.Exists(m, path.Join(p, bin)) { return kit.Path(p, bin) } - if IsWindows() && nfs.ExistsFile(m, path.Join(p, bin)+".exe") { + if IsWindows() && nfs.Exists(m, path.Join(p, bin)+".exe") { return kit.Path(p, bin) + ".exe" } } - if nfs.ExistsFile(m, bin) { + if nfs.Exists(m, bin) { return kit.Path(bin) } return "" diff --git a/base/ctx/command.go b/base/ctx/command.go index a7f0df9e..c1d4674c 100644 --- a/base/ctx/command.go +++ b/base/ctx/command.go @@ -51,6 +51,7 @@ const ( STYLE = "style" DISPLAY = "display" ACTION = "action" + SHIP = "ship" ) const COMMAND = "command" @@ -116,7 +117,7 @@ func FileURI(dir string) string { } else if ice.Info.Make.Path != "" && strings.HasPrefix(dir, ice.Info.Make.Path+ice.PS) { dir = strings.TrimPrefix(dir, ice.Info.Make.Path+ice.PS) } - } else if nfs.ExistsFile(ice.Pulse, path.Join(ice.SRC, dir)) { + } else if nfs.Exists(ice.Pulse, path.Join(ice.SRC, dir)) { dir = path.Join(ice.SRC, dir) } return path.Join(ice.PS, ice.REQUIRE, dir) @@ -147,7 +148,7 @@ func GetFileCmd(dir string) string { } func GetCmdFile(m *ice.Message, cmds string) (file string) { m.Search(cmds, func(key string, cmd *ice.Command) { - if file = strings.TrimPrefix(FileURI(kit.Split(cmd.FileLine(), ice.DF)[0]), "/require/"); !nfs.ExistsFile(m, file) { + if file = strings.TrimPrefix(FileURI(kit.Split(cmd.FileLine(), ice.DF)[0]), "/require/"); !nfs.Exists(m, file) { file = path.Join(ice.ISH_PLUGED, file) } }) diff --git a/base/gdb/routine.go b/base/gdb/routine.go index 4d8b49cd..a04b83b1 100644 --- a/base/gdb/routine.go +++ b/base/gdb/routine.go @@ -15,6 +15,7 @@ func init() { mdb.CREATE: {Name: "create name cmd", Hand: func(m *ice.Message, arg ...string) { m.Go(func() { cb := m.OptionCB("") + m.OptionDefault(ice.CMD, logs.FileLine(cb)) h := mdb.HashCreate(m, m.OptionSimple(mdb.NAME, ice.CMD), mdb.STATUS, START) defer func() { if e := recover(); e == nil { diff --git a/base/log/debug.go b/base/log/debug.go index b2b0aa31..5ddcb6eb 100644 --- a/base/log/debug.go +++ b/base/log/debug.go @@ -18,8 +18,7 @@ func init() { DEBUG: {Name: "debug level=error,bench,debug,error,watch offset filter auto doc", Help: "后台日志", Actions: ice.Actions{ "doc": {Help: "文档", Hand: func(m *ice.Message, arg ...string) { m.ProcessOpen("https://pkg.go.dev/std") }}, }, Hand: func(m *ice.Message, arg ...string) { - offset := kit.Int(kit.Select("0", arg, 1)) - stats := map[string]int{} + offset, stats := kit.Int(kit.Select("0", arg, 1)), map[string]int{} switch arg[0] { case BENCH, ERROR, DEBUG: m.Cmd(nfs.CAT, ice.VAR_LOG+arg[0]+".log", func(line string, index int) { @@ -27,8 +26,7 @@ func init() { return } ls := strings.SplitN(line, ice.SP, 6) - m.Push(mdb.TIME, ls[0]+ice.SP+ls[1]) - m.Push(mdb.ID, ls[2]) + m.Push(mdb.TIME, ls[0]+ice.SP+ls[1]).Push(mdb.ID, ls[2]) i := strings.LastIndex(ls[5], ice.SP) if strings.HasPrefix(ls[5][i+1:], ice.BASE) || strings.HasPrefix(ls[5][i+1:], ice.CORE) || strings.HasPrefix(ls[5][i+1:], ice.MISC) { m.Push(nfs.PATH, ice.USR_ICEBERGS) @@ -45,7 +43,7 @@ func init() { m.Push(nfs.FILE, "init.go") m.Push(nfs.LINE, "90") } - if ls[4] == "cmds" { + if ls[4] == ice.LOG_CMDS { _ls := strings.SplitN(ls[5], ice.SP, 2) ls[4] = _ls[0] ls[5] = _ls[1] @@ -55,9 +53,7 @@ func init() { ls[5] = _ls[1] } } - m.Push("ship", ls[3]) - m.Push(ctx.ACTION, ls[4]) - m.Push(mdb.TEXT, ls[5]) + m.Push(ctx.SHIP, ls[3]).Push(ctx.ACTION, ls[4]).Push(nfs.CONTENT, ls[5]) stats[ls[4]]++ }) case WATCH: @@ -66,17 +62,12 @@ func init() { return } ls := strings.SplitN(line, ice.SP, 6) - m.Push(mdb.TIME, ls[0]+ice.SP+ls[1]) - m.Push(mdb.ID, ls[2]) - m.Push("ship", ls[3]) - + m.Push(mdb.TIME, ls[0]+ice.SP+ls[1]).Push(mdb.ID, ls[2]) i := strings.LastIndex(ls[5], ice.SP) m.Push(nfs.PATH, ice.USR_ICEBERGS) m.Push(nfs.FILE, strings.TrimSpace(strings.Split(ls[5][i:], ice.DF)[0])) m.Push(nfs.LINE, strings.TrimSpace(strings.Split(ls[5][i:], ice.DF)[1])) - - m.Push(ctx.ACTION, ls[4]) - m.Push(mdb.TEXT, ls[5][:i]) + m.Push(ctx.SHIP, ls[3]).Push(ctx.ACTION, ls[4]).Push(nfs.CONTENT, ls[5][:i]) stats[ls[4]]++ }) } diff --git a/base/log/log.go b/base/log/log.go index 84decdbc..aaaba506 100644 --- a/base/log/log.go +++ b/base/log/log.go @@ -25,11 +25,10 @@ func (f *Frame) Begin(m *ice.Message, arg ...string) { ice.Info.Log = func(m *ice.Message, p, l, s string) { f.p <- &Log{p: p, l: l, s: s} } } func (f *Frame) Start(m *ice.Message, arg ...string) { - m.Option("_lock", m.PrefixKey()) - mdb.Confm(m, FILE, nil, func(key string, value ice.Map) { - if f, p, e := logs.CreateFile(kit.Format(value[nfs.PATH])); e == nil { - value[FILE] = bufio.NewWriter(f) + mdb.Confm(m, FILE, nil, func(k string, v ice.Map) { + if f, p, e := logs.CreateFile(kit.Format(v[nfs.PATH])); e == nil { m.Logs(nfs.SAVE, nfs.FILE, p) + v[FILE] = bufio.NewWriter(f) } }) for { @@ -96,6 +95,7 @@ var Index = &ice.Context{Name: LOG, Help: "日志模块", Configs: ice.Configs{ SHOW: {Name: SHOW, Help: "日志分流", Value: kit.Dict()}, }, Commands: ice.Commands{ ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { + ice.Info.Load(m, TAIL) mdb.Confm(m, FILE, nil, func(key string, value ice.Map) { kit.For(value[mdb.LIST], func(index int, k string) { m.Conf(SHOW, kit.Keys(k, FILE), key) }) }) @@ -103,7 +103,7 @@ var Index = &ice.Context{Name: LOG, Help: "日志模块", Configs: ice.Configs{ kit.For(value[mdb.LIST], func(index int, k string) { m.Conf(SHOW, kit.Keys(k, VIEW), key) }) }) }}, - ice.CTX_EXIT: {Hand: func(m *ice.Message, arg ...string) {}}, + ice.CTX_EXIT: {Hand: func(m *ice.Message, arg ...string) { ice.Info.Save(m, TAIL) }}, }} func init() { ice.Index.Register(Index, &Frame{}, TAIL) } diff --git a/base/log/tail.go b/base/log/tail.go index e2eb190c..3379a8c8 100644 --- a/base/log/tail.go +++ b/base/log/tail.go @@ -1,9 +1,6 @@ package log import ( - "bufio" - "io" - ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/cli" "shylinux.com/x/icebergs/base/mdb" @@ -13,8 +10,8 @@ import ( func _tail_create(m *ice.Message, arg ...string) { h := mdb.HashCreate(m, arg) - kit.For(kit.Split(m.Option(FILE)), func(file string) { - m.Options(cli.CMD_OUTPUT, Pipe(m, func(text string) { mdb.ZoneInsert(m, h, FILE, file, nfs.SIZE, len(text), mdb.TEXT, text) }), mdb.CACHE_CLEAR_ON_EXIT, ice.TRUE) + kit.For(kit.Split(m.Option(nfs.FILE)), func(file string) { + m.Options(cli.CMD_OUTPUT, nfs.Pipe(m, func(text string) { mdb.ZoneInsert(m, h, nfs.FILE, file, nfs.SIZE, len(text), mdb.TEXT, text) }), mdb.CACHE_CLEAR_ON_EXIT, ice.TRUE) m.Cmd(cli.DAEMON, TAIL, "-n", "0", "-f", file) }) } @@ -33,20 +30,11 @@ func init() { switch arg[0] { case mdb.NAME: m.Push(arg[0], kit.Split(m.Option(FILE), ice.PS)) - case FILE: - m.Cmdy(nfs.DIR, kit.Select(nfs.PWD, arg, 1), nfs.PATH).RenameAppend(nfs.PATH, FILE).ProcessAgain() + case nfs.FILE: + m.Cmdy(nfs.DIR, kit.Select(nfs.PWD, arg, 1), nfs.PATH).RenameAppend(nfs.PATH, nfs.FILE).ProcessAgain() } }}, mdb.CREATE: {Hand: func(m *ice.Message, arg ...string) { _tail_create(m, arg...) }}, }, mdb.PageZoneAction(mdb.SHORT, mdb.NAME, mdb.FIELDS, "time,name,file,count", mdb.FIELD, "time,id,file,size,text"))}, }) } -func Pipe(m *ice.Message, cb func(string)) io.WriteCloser { - r, w := io.Pipe() - m.Go(func() { - for bio := bufio.NewScanner(r); bio.Scan(); { - cb(bio.Text()) - } - }) - return w -} diff --git a/base/log/watch.go b/base/log/watch.go index be08daa0..d7954593 100644 --- a/base/log/watch.go +++ b/base/log/watch.go @@ -2,9 +2,9 @@ package log import ( "path" - "strings" ice "shylinux.com/x/icebergs" + "shylinux.com/x/icebergs/base/ctx" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" kit "shylinux.com/x/toolkits" @@ -15,21 +15,14 @@ const WATCH = "watch" func init() { Index.MergeCommands(ice.Commands{ WATCH: {Name: "watch auto", Help: "记录", Hand: func(m *ice.Message, arg ...string) { - operate := map[string]int{} - for _, line := range strings.Split(m.Cmdx(nfs.CAT, path.Join(ice.VAR_LOG, "watch.log")), ice.NL) { - ls := kit.Split(line, "", " ", " ") - if len(ls) < 5 { - continue - } - m.Push(mdb.TIME, ls[0]+ice.SP+ls[1]) - m.Push("order", ls[2]) - m.Push("ship", ls[3]) - m.Push("source", kit.Slice(ls, -1)[0]) - m.Push("operate", ls[4]) - m.Push("content", kit.Join(kit.Slice(ls, 5, -1), ice.SP)) - operate[ls[4]]++ - } - m.StatusTimeCount(operate) + stats := map[string]int{} + m.Cmd(nfs.CAT, path.Join(ice.VAR_LOG, "watch.log"), func(text string) { + ls := kit.Split(text) + m.Push(mdb.TIME, ls[0]+ice.SP+ls[1]).Push(mdb.ID, ls[2]).Push(nfs.SOURCE, kit.Slice(ls, -1)[0]) + m.Push(ctx.SHIP, ls[3]).Push(ctx.ACTION, ls[4]).Push(nfs.CONTENT, kit.Join(kit.Slice(ls, 5, -1), ice.SP)) + stats[ls[4]]++ + }) + m.StatusTimeCount(stats) }}, }) } diff --git a/base/mdb/list.go b/base/mdb/list.go index 08c2db0d..4c507938 100644 --- a/base/mdb/list.go +++ b/base/mdb/list.go @@ -169,8 +169,8 @@ func PrevPageLimit(m *ice.Message, total string, arg ...string) { } func OptionPages(m *ice.Message, arg ...string) (page int, size int) { - m.Option(CACHE_LIMIT, kit.Select(m.Option(CACHE_LIMIT), arg, 0)) - m.Option(CACHE_OFFEND, kit.Select(m.Option(CACHE_OFFEND), arg, 1)) + m.Option(CACHE_OFFEND, kit.Select(m.Option(CACHE_OFFEND), arg, 0)) + m.Option(CACHE_LIMIT, kit.Select(m.Option(CACHE_LIMIT), arg, 1)) m.Option(CACHE_FILTER, kit.Select(m.Option(CACHE_FILTER), arg, 2)) m.Option(LIMIT, kit.Select(m.Option(LIMIT), arg, 0)) m.Option(OFFEND, kit.Select(m.Option(OFFEND), arg, 1)) diff --git a/base/nfs/cat.go b/base/nfs/cat.go index 5121548d..a7c9dbf4 100644 --- a/base/nfs/cat.go +++ b/base/nfs/cat.go @@ -1,10 +1,11 @@ package nfs import ( - "bufio" "bytes" "encoding/json" "io" + "io/ioutil" + "os" "path" "strings" @@ -14,70 +15,44 @@ import ( kit "shylinux.com/x/toolkits" ) -func _cat_find(m *ice.Message, file string) (io.ReadCloser, error) { +func _cat_find(m *ice.Message, p string) (io.ReadCloser, error) { if m.Option(CAT_CONTENT) != "" { return NewReadCloser(bytes.NewBufferString(m.Option(CAT_CONTENT))), nil } - return OpenFile(m, path.Join(m.Option(DIR_ROOT), file)) + return OpenFile(m, path.Join(m.Option(DIR_ROOT), p)) } -func _cat_size(m *ice.Message, file string) (nline int) { - if f, e := OpenFile(m, file); !m.Warn(e) { - defer f.Close() - for bio := bufio.NewScanner(f); bio.Scan(); nline++ { - bio.Text() - } - } - return nline +func _cat_hash(m *ice.Message, p string) (h string) { + Open(m, p, func(r io.Reader) { h = kit.Hashs(r) }) + return } -func _cat_hash(m *ice.Message, file string) string { - if f, e := OpenFile(m, file); !m.Warn(e) { - defer f.Close() - return kit.Hashs(f) - } - return "" +func _cat_line(m *ice.Message, p string) (n int) { + Open(m, p, func(r io.Reader) { kit.For(r, func(s string) { n++ }) }) + return } -func _cat_list(m *ice.Message, file string) { - if m.Option(CAT_CONTENT) == "" && !aaa.Right(m, file) { +func _cat_list(m *ice.Message, p string) { + if m.Option(CAT_CONTENT) == "" && !aaa.Right(m, p) { return } - f, e := _cat_find(m, file) - if m.Warn(e, ice.ErrNotFound, file) { + f, e := _cat_find(m, p) + if m.Warn(e, ice.ErrNotFound, p) { return } defer f.Close() switch cb := m.OptionCB("").(type) { case func(string, int) string: list := []string{} - for bio, i := bufio.NewScanner(f), 0; bio.Scan(); i++ { - list = append(list, cb(bio.Text(), i)) - } + kit.For(f, func(s string, i int) { list = append(list, cb(s, i)) }) m.Echo(strings.Join(list, ice.NL) + ice.NL) case func(string, int): - for bio, i := bufio.NewScanner(f), 0; bio.Scan(); i++ { - cb(bio.Text(), i) - } + kit.For(f, cb) case func(string): - for bio := bufio.NewScanner(f); bio.Scan(); { - cb(bio.Text()) - } + kit.For(f, cb) case func([]string, string): - for bio := bufio.NewScanner(f); bio.Scan(); { - cb(kit.Split(bio.Text()), bio.Text()) - } + kit.For(f, cb) case nil: - buf, size := make([]byte, 10*ice.MOD_BUFS), 0 - for { - if n, e := f.Read(buf[size:]); !m.Warn(e, ice.ErrNotValid, file) { - m.Logs(LOAD, FILE, file, SIZE, n) - if size += n; size >= len(buf) { - buf = append(buf, make([]byte, ice.MOD_BUFS)...) - continue - } - } - buf = buf[:size] - break + if b, e := ioutil.ReadAll(f); !m.Warn(e) { + m.Echo(string(b)).StatusTime(FILE, p, SIZE, len(b)) } - m.Echo(string(buf)).StatusTime(FILE, file, SIZE, size) default: m.ErrorNotImplement(cb) } @@ -85,26 +60,27 @@ func _cat_list(m *ice.Message, file string) { const ( CAT_CONTENT = "cat_content" + CONFIGURE = "configure" + TEMPLATE = "template" + STDIO = "stdio" - STDIO = "stdio" + TAGS = "tags" MODULE = "module" SOURCE = "source" - SCRIPT = "script" - BINARY = "binary" TARGET = "target" - TAGS = "tags" + BINARY = "binary" + SCRIPT = "script" - TEMPLATE = "template" - VERSION = "version" - MASTER = "master" - BRANCH = "branch" - REMOTE = "remote" - ORIGIN = "origin" - REPOS = "repos" + REPOS = "repos" + ORIGIN = "origin" + REMOTE = "remote" + BRANCH = "branch" + MASTER = "master" + VERSION = "version" ) const ( - SVG = ice.SVG HTML = ice.HTML + SVG = ice.SVG CSS = ice.CSS JS = ice.JS GO = ice.GO @@ -113,13 +89,12 @@ const ( CSV = ice.CSV JSON = ice.JSON - PY = "py" - MD = "md" - TXT = "txt" - XML = "xml" - YML = "yml" - ZML = "zml" - IML = "iml" + CONF = "conf" + XML = "xml" + YML = "yml" + TXT = "txt" + MD = "md" + PY = "py" PNG = "png" JPG = "jpg" @@ -136,41 +111,75 @@ const CAT = "cat" func init() { Index.MergeCommands(ice.Commands{ CAT: {Name: "cat path auto", Help: "文件", Actions: ice.MergeActions(ice.Actions{ice.CTX_INIT: mdb.AutoConfig(SOURCE, kit.DictList( - HTML, CSS, JS, GO, SH, SHY, CSV, JSON, PY, MD, TXT, XML, YML, ZML, IML, - ice.LICENSE, ice.MAKEFILE, "configure", "conf", + HTML, CSS, JS, GO, SH, PY, SHY, CSV, JSON, CONFIGURE, CONF, XML, YML, TXT, MD, ice.LICENSE, ice.MAKEFILE, ))}), Hand: func(m *ice.Message, arg ...string) { if len(arg) == 0 || strings.HasSuffix(arg[0], ice.PS) { m.Cmdy(DIR, arg) - return + } else { + _cat_list(m.Logs(FIND, m.OptionSimple(DIR_ROOT)), arg[0]) } - if m.Option(DIR_ROOT) != "" { - m.Logs(mdb.SELECT, m.OptionSimple(DIR_ROOT)) - } - _cat_list(m, arg[0]) }}, }) } + +type templateMessage interface { + PrefixKey(...string) string + Cmdx(...ice.Any) string +} + +func Template(m templateMessage, p string, arg ...ice.Any) string { + return kit.Renders(kit.Format(TemplateText(m, p), arg...), m) +} +func TemplateText(m templateMessage, p string) string { + return m.Cmdx(CAT, path.Join(m.PrefixKey(), path.Base(p)), kit.Dict(DIR_ROOT, ice.SRC_TEMPLATE)) +} func IsSourceFile(m *ice.Message, ext string) bool { return mdb.Conf(m, Prefix(CAT), kit.Keym(SOURCE, ext)) == ice.TRUE } -func OptionLoad(m *ice.Message, file string) *ice.Message { - if f, e := OpenFile(m, file); e == nil { - defer f.Close() +func OptionLoad(m *ice.Message, p string) *ice.Message { + Open(m, p, func(r io.Reader) { var data ice.Any - m.Assert(json.NewDecoder(f).Decode(&data)) - kit.For(data, func(key string, value ice.Any) { m.Option(key, kit.Simple(value)) }) - } + m.Assert(json.NewDecoder(r).Decode(&data)) + kit.For(data, func(k string, v ice.Any) { m.Optionv(k, v) }) + }) return m } - -type templateMessage interface { - Cmdx(arg ...ice.Any) string - PrefixKey(...string) string +func Open(m *ice.Message, p string, cb ice.Any) { + if strings.HasSuffix(p, PS) { + if ls, e := ReadDir(m, p); !m.Warn(e) { + switch cb := cb.(type) { + case func([]os.FileInfo): + cb(ls) + case func(os.FileInfo): + kit.For(ls, cb) + default: + m.ErrorNotImplement(cb) + } + } + } else if f, e := OpenFile(m, p); !m.Warn(e, ice.ErrNotFound, p) { + defer f.Close() + switch cb := cb.(type) { + case func(io.Reader, os.FileInfo): + s, _ := StatFile(m, p) + cb(f, s) + case func(io.Reader): + cb(f) + case func(string): + if b, e := ioutil.ReadAll(f); !m.Warn(e) { + cb(string(b)) + } + default: + m.ErrorNotImplement(cb) + } + } } - -func Template(m templateMessage, file string, arg ...ice.Any) string { - return kit.Renders(kit.Format(TemplateText(m, file), arg...), m) +func ReadAll(m *ice.Message, r io.Reader) []byte { + if b, e := ioutil.ReadAll(r); !m.Warn(e) { + return b + } + return nil } -func TemplateText(m templateMessage, file string) string { - return m.Cmdx(CAT, path.Join(m.PrefixKey(), path.Base(file)), kit.Dict(DIR_ROOT, ice.SRC_TEMPLATE)) +func ReadFile(m *ice.Message, p string) (b []byte, e error) { + Open(m, p, func(r io.Reader) { b, e = ioutil.ReadAll(r) }) + return } diff --git a/base/nfs/dir.go b/base/nfs/dir.go index 13278814..59c4300e 100644 --- a/base/nfs/dir.go +++ b/base/nfs/dir.go @@ -12,50 +12,36 @@ import ( kit "shylinux.com/x/toolkits" ) -func _dir_size(m *ice.Message, dir string) int { - if ls, e := ReadDir(m, dir); !m.Warn(e) { - return len(ls) - } - return 0 +func _dir_size(m *ice.Message, p string) (n int) { + Open(m, p+PS, func(ls []os.FileInfo) { n = len(ls) }) + return } -func _dir_hash(m *ice.Message, dir string) string { - if ls, e := ReadDir(m, dir); !m.Warn(e) { - meta := []string{} - for _, s := range ls { - meta = append(meta, kit.Format("%s%d%s", s.Name(), s.Size(), s.ModTime())) - } - return kit.Hashs(meta) - } +func _dir_hash(m *ice.Message, p string) (h string) { + list := []string{} + Open(m, p+PS, func(s os.FileInfo) { list = append(list, kit.Format("%s%d%s", s.Name(), s.Size(), s.ModTime())) }) + kit.If(len(list) > 0, func() { h = kit.Hashs(list) }) return "" } func _dir_list(m *ice.Message, root string, dir string, level int, deep bool, dir_type string, dir_reg *regexp.Regexp, fields []string) *ice.Message { ls, _ := ReadDir(m, path.Join(root, dir)) if len(ls) == 0 { if s, e := StatFile(m, path.Join(root, dir)); e == nil && !s.IsDir() { - _ls, _ := ReadDir(m, path.Dir(path.Join(root, dir))) - for _, s := range _ls { - if s.Name() == path.Base(dir) { - ls = append(ls, s) - } - } + Open(m, path.Dir(path.Join(root, dir))+PS, func(s os.FileInfo) { kit.If(s.Name() == path.Base(dir), func() { ls = append(ls, s) }) }) dir, deep = path.Dir(dir), false } } - for _, f := range ls { - if f.Name() == ice.PT || f.Name() == ".." { + for _, s := range ls { + if s.Name() == ice.PT || s.Name() == ".." || strings.HasPrefix(s.Name(), ice.PT) && dir_type != TYPE_ALL { continue } - if strings.HasPrefix(f.Name(), ice.PT) && dir_type != TYPE_ALL { - continue - } - p, _dir := path.Join(root, dir, f.Name()), path.Join(dir, f.Name()) - isDir := f.IsDir() || kit.IsDir(p) - if !(dir_type == TYPE_CAT && isDir || dir_type == TYPE_DIR && !isDir) && (dir_reg == nil || dir_reg.MatchString(f.Name())) { + p, pp := path.Join(root, dir, s.Name()), path.Join(dir, s.Name()) + isDir := s.IsDir() || kit.IsDir(p) + if !(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(f os.FileInfo, p string): - cb(f, p) + case func(os.FileInfo, string): + cb(s, p) continue - case func(p string): + case func(string): cb(p) continue case nil: @@ -65,34 +51,34 @@ func _dir_list(m *ice.Message, root string, dir string, level int, deep bool, di for _, field := range fields { switch field { case mdb.TIME: - m.Push(field, f.ModTime().Format(ice.MOD_TIME)) + m.Push(field, s.ModTime().Format(ice.MOD_TIME)) case mdb.TYPE: m.Push(field, kit.Select(CAT, DIR, isDir)) case TREE: if level == 0 { - m.Push(field, f.Name()) + m.Push(field, s.Name()) } else { - m.Push(field, strings.Repeat("| ", level-1)+"|-"+f.Name()) + m.Push(field, strings.Repeat("| ", level-1)+"|-"+s.Name()) } case FULL: m.Push(field, p+kit.Select("", ice.PS, isDir)) case PATH: - m.Push(field, _dir+kit.Select("", ice.PS, isDir)) + m.Push(field, pp+kit.Select("", ice.PS, isDir)) case FILE: - m.Push(field, f.Name()+kit.Select("", ice.PS, isDir)) + m.Push(field, s.Name()+kit.Select("", ice.PS, isDir)) case NAME: - m.Push(field, f.Name()) + m.Push(field, s.Name()) case SIZE: if isDir { m.Push(field, _dir_size(m, p)) } else { - m.Push(field, kit.FmtSize(f.Size())) + m.Push(field, kit.FmtSize(s.Size())) } case LINE: if isDir { m.Push(field, _dir_size(m, p)) } else { - m.Push(field, _cat_size(m, p)) + m.Push(field, _cat_line(m, p)) } case mdb.HASH, "hashs": h := "" @@ -106,10 +92,10 @@ func _dir_list(m *ice.Message, root string, dir string, level int, deep bool, di if strings.Contains(p, "ice.windows.") { m.PushDownload(mdb.LINK, "ice.exe", p) } else { - m.PushDownload(mdb.LINK, kit.Select("", f.Name(), !isDir), p) + m.PushDownload(mdb.LINK, kit.Select("", s.Name(), !isDir), p) } case mdb.SHOW: - switch p := kit.MergeURL("/share/local/"+p, ice.POD, m.Option(ice.MSG_USERPOD)); kit.Ext(f.Name()) { + switch p := kit.MergeURL("/share/local/"+p, ice.POD, m.Option(ice.MSG_USERPOD)); kit.Ext(s.Name()) { case PNG, JPG: m.PushImages(field, p) case MP4: @@ -128,26 +114,25 @@ func _dir_list(m *ice.Message, root string, dir string, level int, deep bool, di } } if deep && isDir { - switch f.Name() { + switch s.Name() { case "node_modules", "pluged", "target", "trash": continue } - _dir_list(m, root, _dir, level+1, deep, dir_type, dir_reg, fields) + _dir_list(m, root, pp, level+1, deep, dir_type, dir_reg, fields) } } return m } const ( + SRC = "src/" + USR = "usr/" + TYPE_ALL = "all" TYPE_CAT = "cat" TYPE_DIR = "dir" TYPE_BOTH = "both" - SRC = "src/" - USR = "usr/" -) -const ( DIR_ROOT = "dir_root" DIR_TYPE = "dir_type" DIR_DEEP = "dir_deep" @@ -156,8 +141,7 @@ const ( DIR_DEF_FIELDS = "time,size,path,action" DIR_WEB_FIELDS = "time,size,path,link,action" DIR_CLI_FIELDS = "path,size,time" -) -const ( + ROOT = "root" TREE = "tree" FULL = "full" @@ -166,9 +150,6 @@ const ( NAME = "name" SIZE = "size" LINE = "line" - - OPENS = "opens" - FIND = "find" ) const DIR = "dir" @@ -178,21 +159,19 @@ func init() { ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { aaa.White(m, ice.SRC, ice.BIN, ice.USR) aaa.Black(m, ice.USR_LOCAL) - }}, mdb.UPLOAD: {}, + }}, mdb.SEARCH: {Hand: func(m *ice.Message, arg ...string) { if arg[0] == mdb.FOREACH && arg[1] == "" && m.Cmdx("host", "islocal", m.Option(ice.MSG_USERIP)) == ice.OK { - for _, p := range []string{"Desktop", "Documents", "Downloads", "Pictures"} { - p := kit.HomePath(p) + kit.For([]string{"Desktop", "Documents", "Downloads", "Pictures"}, func(p string) { + p = kit.HomePath(p) m.Cmd(DIR, PWD, mdb.NAME, mdb.TIME, kit.Dict(DIR_ROOT, p)).SortStrR(mdb.TIME).TablesLimit(5, func(value ice.Maps) { name := value[mdb.NAME] - if len(kit.TrimExt(name)) > 30 { - name = name[:10] + ".." + name[len(name)-10:] - } + kit.If(len(kit.TrimExt(name)) > 30, func() { name = name[:10] + ".." + name[len(name)-10:] }) m.PushSearch(mdb.TYPE, OPENS, mdb.NAME, name, mdb.TEXT, path.Join(p, value[mdb.NAME])) }) - } + }) } - }}, + }}, mdb.UPLOAD: {}, TRASH: {Hand: func(m *ice.Message, arg ...string) { m.Cmd(TRASH, mdb.CREATE, m.Option(PATH)) }}, }, Hand: func(m *ice.Message, arg ...string) { root, dir := kit.Select(PWD, m.Option(DIR_ROOT)), kit.Select(PWD, arg, 0) @@ -208,11 +187,12 @@ func init() { }) } +var bind = []string{ + "usr/icebergs/core/chat/", "usr/volcanos/panel/", + "usr/icebergs/core/", "usr/volcanos/plugin/local/", +} + func Relative(m *ice.Message, p string) string { - var bind = []string{ - "usr/icebergs/core/chat/", "usr/volcanos/panel/", - "usr/icebergs/core/", "usr/volcanos/plugin/local/", - } for i := 0; i < len(bind); i += 2 { if strings.HasPrefix(p, bind[i]) { return strings.Replace(p, bind[i], bind[i+1], 1) @@ -229,9 +209,9 @@ func SplitPath(m *ice.Message, p string) []string { return []string{strings.Join(ls[:1], ice.PS) + ice.PS, strings.Join(ls[1:], ice.PS)} } } -func Dir(m *ice.Message, sort string) *ice.Message { - m.Copy(m.Cmd(DIR, PWD, kit.Dict(DIR_TYPE, TYPE_DIR)).Sort(sort)) - m.Copy(m.Cmd(DIR, PWD, kit.Dict(DIR_TYPE, TYPE_CAT)).Sort(sort)) +func Dir(m *ice.Message, field string) *ice.Message { + m.Copy(m.Cmd(DIR, PWD, kit.Dict(DIR_TYPE, TYPE_DIR)).Sort(field)) + m.Copy(m.Cmd(DIR, PWD, kit.Dict(DIR_TYPE, TYPE_CAT)).Sort(field)) return m } func DirDeepAll(m *ice.Message, root, dir string, cb func(ice.Maps), arg ...string) *ice.Message { diff --git a/base/nfs/grep.go b/base/nfs/grep.go index a87fc62c..ea335732 100644 --- a/base/nfs/grep.go +++ b/base/nfs/grep.go @@ -8,6 +8,11 @@ import ( kit "shylinux.com/x/toolkits" ) +const ( + FIND = "find" + OPENS = "opens" +) + const GREP = "grep" func init() { @@ -15,11 +20,11 @@ func init() { Index.MergeCommands(ice.Commands{ GREP: {Name: "grep word file path auto", Help: "搜索", Hand: func(m *ice.Message, arg ...string) { m.Options(mdb.VALUE, arg[0], CMD_DIR, kit.Select("", arg, 2)) - for _, line := range strings.Split(m.Cmdx("cli.system", GREP, "--exclude=.[a-z]*", "--exclude-dir=.[a-z]*", "--exclude-dir=node_modules", "-rni", arg[0], kit.Select(ice.PT, arg, 1)), ice.NL) { - if ls := strings.SplitN(line, ice.DF, 3); len(ls) > 2 { - m.Push(FILE, strings.TrimPrefix(ls[0], PWD)).Push(LINE, ls[1]).Push(mdb.TEXT, ls[2]) + kit.For(strings.Split(m.Cmdx("cli.system", GREP, "--exclude=.[a-z]*", "--exclude-dir=.[a-z]*", "-rni", arg[0], kit.Select(ice.PT, arg, 1)), ice.NL), func(s string) { + if ls := strings.SplitN(s, ice.DF, 3); len(ls) > 2 { + m.Push(FILE, strings.TrimPrefix(ls[0], PWD)).Push(s, ls[1]).Push(mdb.TEXT, ls[2]) } - } + }) m.StatusTimeCount(PATH, m.Option(CMD_DIR)) }}, }) diff --git a/base/nfs/hex.go b/base/nfs/hex.go index ca3e8284..e19026a8 100644 --- a/base/nfs/hex.go +++ b/base/nfs/hex.go @@ -21,10 +21,7 @@ func init() { m.Cmdy(DIR, kit.Slice(arg, 0, 1)) return } - if f, e := os.Open(arg[0]); !m.Warn(e, ice.ErrNotFound, arg[0]) { - defer f.Close() - s, _ := f.Stat() - var r io.Reader = f + Open(m, arg[0], func(r io.Reader, s os.FileInfo) { switch arg[1] { case "gzip": if g, e := gzip.NewReader(r); !m.Warn(e) { @@ -37,15 +34,12 @@ func init() { } buf := make([]byte, kit.Int(kit.Select("1024", arg, 2))) n, _ := r.Read(buf) - for i := 0; i < n; i++ { - if i%8 == 0 { - m.Push("n", kit.Format("%04d", i)) - } - if m.Push(kit.Format(i%8), hex.EncodeToString(buf[i:i+1])); i%8 == 7 { - m.Push("text", string(buf[i-7:i+1])) - } - } + kit.For(n, func(i int) { + kit.If(i%8 == 0, func() { m.Push(OFFSET, kit.Format("%04d", i)) }) + m.Push(kit.Format(i%8), hex.EncodeToString(buf[i:i+1])) + kit.If(i%8 == 7, func() { m.Push(mdb.TEXT, string(buf[i-7:i+1])) }) + }) m.Status(mdb.TIME, s.ModTime().Format(ice.MOD_TIME), FILE, arg[0], SIZE, kit.FmtSize(s.Size())) - } + }) }}}) } diff --git a/base/nfs/pack.go b/base/nfs/pack.go index e9089e08..6fa53c6f 100644 --- a/base/nfs/pack.go +++ b/base/nfs/pack.go @@ -2,7 +2,6 @@ package nfs import ( "io" - "io/ioutil" "os" "path" "strings" @@ -16,47 +15,41 @@ import ( const PACK = "pack" func init() { - pack := PackFile Index.MergeCommands(ice.Commands{ PACK: {Name: "pack path auto upload create", Help: "文件系统", Actions: ice.Actions{ - mdb.UPLOAD: {Hand: func(m *ice.Message, arg ...string) { - if c, e := DiskFile.OpenFile(m.Option(FILE)); m.Assert(e) { - defer c.Close() - if f, p, e := pack.CreateFile(path.Join(m.Option(PATH), m.Option(mdb.NAME))); m.Assert(e) { - defer f.Close() - if n, e := io.Copy(f, c); m.Assert(e) { - m.Logs(mdb.EXPORT, FILE, p, SIZE, n) - } - } - } - }}, mdb.CREATE: {Name: "create path*=src/hi/hi.txt text*=hello", Hand: func(m *ice.Message, arg ...string) { - if f, p, e := pack.CreateFile(m.Option(PATH)); m.Assert(e) { - defer f.Close() - if n, e := f.Write([]byte(m.Option(mdb.TEXT))); m.Assert(e) { - m.Logs(mdb.EXPORT, FILE, p, SIZE, n) - } - } + OptionFiles(m, PackFile) + Create(m, m.Option(PATH), func(w io.Writer, p string) { + Save(m, w, m.Option(mdb.TEXT), func(n int) { m.Logs(LOAD, FILE, p, SIZE, n) }) + }) + }}, + mdb.REMOVE: {Hand: func(m *ice.Message, arg ...string) { PackFile.Remove(path.Clean(m.Option(PATH))) }}, + mdb.IMPORT: {Hand: func(m *ice.Message, arg ...string) { + OptionFiles(m, DiskFile) + Open(m, path.Join(m.Option(PATH), m.Option(FILE)), func(r io.Reader, p string) { + OptionFiles(m, PackFile) + Create(m, p, func(w io.Writer) { Copy(m, w, r, func(n int) { m.Logs(LOAD, FILE, p, SIZE, n) }) }) + }) + }}, + mdb.EXPORT: {Hand: func(m *ice.Message, arg ...string) { + OptionFiles(m, PackFile) + Open(m, path.Join(m.Option(PATH), m.Option(FILE)), func(r io.Reader, p string) { + OptionFiles(m, DiskFile) + Create(m, p, func(w io.Writer) { Copy(m, w, r, func(n int) { m.Logs(LOAD, FILE, p, SIZE, n) }) }) + }) }}, - mdb.REMOVE: {Hand: func(m *ice.Message, arg ...string) { pack.Remove(path.Clean(m.Option(PATH))) }}, }, Hand: func(m *ice.Message, arg ...string) { - p := kit.Select("", arg, 0) - if p != "" && !strings.HasSuffix(p, PS) { - if f, e := pack.OpenFile(p); e == nil { - defer f.Close() - if b, e := ioutil.ReadAll(f); e == nil { - m.Echo(string(b)) - } - } - return + OptionFiles(m, PackFile) + if p := kit.Select("", arg, 0); p != "" && !strings.HasSuffix(p, PS) { + Open(m, p, func(r io.Reader) { m.Echo(string(ReadAll(m, r))) }) + } else { + Open(m, p+PS, func(s os.FileInfo) { + m.Push(mdb.TIME, s.ModTime().Format(ice.MOD_TIME)) + m.Push(PATH, path.Join(p, s.Name())+kit.Select("", PS, s.IsDir())) + m.Push(SIZE, kit.FmtSize(s.Size())) + }) + m.Sort(PATH).PushAction(mdb.REMOVE).StatusTimeCount() } - ls, _ := pack.ReadDir(p) - for _, f := range ls { - m.Push(mdb.TIME, f.ModTime().Format(ice.MOD_TIME)) - m.Push(PATH, path.Join(p, f.Name())+kit.Select("", PS, f.IsDir())) - m.Push(SIZE, kit.FmtSize(f.Size())) - } - m.Sort(PATH).PushAction(mdb.REMOVE).StatusTimeCount() }}, }) } @@ -66,7 +59,11 @@ var DiskFile = file.NewDiskFile() func init() { file.Init(OptionFiles(ice.Pulse, DiskFile, PackFile)) } -func OptionFiles(m Message, f ...file.File) file.File { +type optionMessage interface { + Optionv(key string, arg ...ice.Any) ice.Any +} + +func OptionFiles(m optionMessage, f ...file.File) file.File { if len(f) > 1 { m.Optionv(ice.MSG_FILES, file.NewMultiFile(f...)) } else if len(f) > 0 { @@ -74,25 +71,18 @@ func OptionFiles(m Message, f ...file.File) file.File { } return m.Optionv(ice.MSG_FILES).(file.File) } -func StatFile(m Message, p string) (os.FileInfo, error) { - return OptionFiles(m).StatFile(p) -} -func OpenFile(m Message, p string) (io.ReadCloser, error) { - return OptionFiles(m).OpenFile(p) -} -func CreateFile(m Message, p string) (io.WriteCloser, string, error) { +func StatFile(m optionMessage, p string) (os.FileInfo, error) { return OptionFiles(m).StatFile(p) } +func OpenFile(m optionMessage, p string) (io.ReadCloser, error) { return OptionFiles(m).OpenFile(p) } +func CreateFile(m optionMessage, p string) (io.WriteCloser, string, error) { return OptionFiles(m).CreateFile(p) } -func AppendFile(m Message, p string) (io.ReadWriteCloser, string, error) { - file := OptionFiles(m) - w, e := file.AppendFile(p) +func AppendFile(m optionMessage, p string) (io.ReadWriteCloser, string, error) { + w, e := OptionFiles(m).AppendFile(p) return w, p, e } -func WriteFile(m Message, p string, b []byte) error { - return OptionFiles(m).WriteFile(p, b) -} +func WriteFile(m optionMessage, p string, b []byte) error { return OptionFiles(m).WriteFile(p, b) } -func ReadDir(m Message, p string) ([]os.FileInfo, error) { +func ReadDir(m optionMessage, p string) ([]os.FileInfo, error) { list, e := OptionFiles(m).ReadDir(p) for i := 0; i < len(list)-1; i++ { for j := i + 1; j < len(list); j++ { @@ -103,85 +93,35 @@ func ReadDir(m Message, p string) ([]os.FileInfo, error) { } return list, e } -func MkdirAll(m Message, p string) string { +func MkdirAll(m optionMessage, p string) string { OptionFiles(m).MkdirAll(p, ice.MOD_DIR) return p } -func RemoveAll(m Message, p string) error { - return OptionFiles(m).RemoveAll(p) -} -func Remove(m Message, p string) error { - return OptionFiles(m).Remove(p) -} -func Rename(m Message, oldname string, newname string) error { +func RemoveAll(m optionMessage, p string) error { return OptionFiles(m).RemoveAll(p) } +func Remove(m optionMessage, p string) error { return OptionFiles(m).Remove(p) } +func Rename(m optionMessage, oldname string, newname string) error { MkdirAll(m, path.Dir(newname)) return OptionFiles(m).Rename(oldname, newname) } -func Symlink(m Message, oldname string, newname string) error { +func Symlink(m optionMessage, oldname string, newname string) error { return OptionFiles(m).Symlink(oldname, newname) } -func Link(m Message, oldname string, newname string) error { +func Link(m optionMessage, oldname string, newname string) error { return OptionFiles(m).Link(oldname, newname) } -type Message interface { - Optionv(key string, arg ...ice.Any) ice.Any -} - -func ExistsFile(m Message, p string) bool { +func Exists(m optionMessage, p string) bool { if _, e := OptionFiles(m).StatFile(p); e == nil { return true } return false } -func ReadFile(m Message, p string) ([]byte, error) { - if f, e := OptionFiles(m).OpenFile(p); e == nil { - defer f.Close() - return ioutil.ReadAll(f) - } else { - return nil, e - } +func NewReadCloser(r io.Reader) io.ReadCloser { return file.NewReadCloser(r) } +func NewWriteCloser(w func([]byte) (int, error), c func() error) io.WriteCloser { + return file.NewWriteCloser(w, c) } -func CloseFile(m Message, p ice.Any) { +func Close(m optionMessage, p ice.Any) { if w, ok := p.(io.Closer); ok { w.Close() } } - -func CopyFile(m *ice.Message, to io.WriteCloser, from io.ReadCloser, cache, total int, cb ice.Any) { - count, buf := 0, make([]byte, cache) - for { - n, e := from.Read(buf) - to.Write(buf[0:n]) - if count += n; count > total { - total = count - } - switch value := count * 100 / total; cb := cb.(type) { - case func(int, int, int): - cb(count, total, value) - case func(int, int): - cb(count, total) - case nil: - default: - m.ErrorNotImplement(cb) - } - if e == io.EOF || m.Warn(e) { - break - } - } -} - -func NewWriteCloser(w func([]byte) (int, error), c func() error) io.WriteCloser { - return file.NewWriteCloser(w, c) -} -func NewReadCloser(r io.Reader) io.ReadCloser { - return file.NewReadCloser(r) -} -func NewCloser(c func() error) io.WriteCloser { - return file.NewWriteCloser(func(buf []byte) (int, error) { return 0, nil }, c) -} - -func CatFile(m *ice.Message, p string) string { - b, _ := ioutil.ReadFile(p) - return strings.TrimSpace(string(b)) -} diff --git a/base/nfs/save.go b/base/nfs/save.go index 36e820b4..9059b2f0 100644 --- a/base/nfs/save.go +++ b/base/nfs/save.go @@ -3,7 +3,6 @@ package nfs import ( "fmt" "io" - "os" "path" ice "shylinux.com/x/icebergs" @@ -11,51 +10,37 @@ import ( ) func _defs_file(m *ice.Message, name string, text ...string) { - if ExistsFile(m, path.Join(m.Option(DIR_ROOT), name)) { + if Exists(m, path.Join(m.Option(DIR_ROOT), name)) { return } for i, v := range text { - b, _ := kit.Render(v, m) - text[i] = string(b) + if b, e := kit.Render(v, m); !m.Warn(e) { + text[i] = string(b) + } } _save_file(m, name, text...) } func _save_file(m *ice.Message, name string, text ...string) { - if f, p, e := CreateFile(m, path.Join(m.Option(DIR_ROOT), name)); m.Assert(e) { - defer f.Close() + Create(m, path.Join(m.Option(DIR_ROOT), name), func(w io.Writer, p string) { defer m.Echo(p) - for _, v := range text { - if n, e := fmt.Fprint(f, v); m.Assert(e) { - m.Logs(SAVE, FILE, p, SIZE, n) - } - } - } + kit.For(text, func(s string) { Save(m, w, s, func(n int) { m.Logs(SAVE, FILE, p, SIZE, n) }) }) + }) } func _push_file(m *ice.Message, name string, text ...string) { - if f, p, e := AppendFile(m, path.Join(m.Option(DIR_ROOT), name)); m.Assert(e) { - defer f.Close() + Append(m, path.Join(m.Option(DIR_ROOT), name), func(w io.Writer, p string) { defer m.Echo(p) - for _, k := range text { - if n, e := fmt.Fprint(f, k); m.Assert(e) { - m.Logs(SAVE, FILE, p, SIZE, n) - } - } - } + kit.For(text, func(s string) { Save(m, w, s, func(n int) { m.Logs(SAVE, FILE, p, SIZE, n) }) }) + }) } func _copy_file(m *ice.Message, name string, from ...string) { - if f, p, e := CreateFile(m, path.Join(m.Option(DIR_ROOT), name)); m.Assert(e) { - defer f.Close() + Create(m, path.Join(m.Option(DIR_ROOT), name), func(w io.Writer, p string) { defer m.Echo(p) - for _, v := range from { - if s, e := OpenFile(m, path.Join(m.Option(DIR_ROOT), v)); !m.Warn(e, ice.ErrNotFound, v) { - defer s.Close() - if n, e := io.Copy(f, s); !m.Warn(e, ice.ErrNotValid, v) { - m.Logs(LOAD, FILE, v, SIZE, n) - m.Logs(SAVE, FILE, p, SIZE, n) - } - } - } - } + kit.For(from, func(f string) { + Open(m, path.Join(m.Option(DIR_ROOT), f), func(r io.Reader) { + Copy(m, w, r, func(n int) { m.Logs(LOAD, FILE, f, SIZE, n).Logs(SAVE, FILE, p, SIZE, n) }) + }) + }) + }) } func _link_file(m *ice.Message, name string, from string) { if m.Warn(from == "", ice.ErrNotValid, FROM) { @@ -63,29 +48,29 @@ func _link_file(m *ice.Message, name string, from string) { } name = path.Join(m.Option(DIR_ROOT), name) from = path.Join(m.Option(DIR_ROOT), from) - if m.Warn(!ExistsFile(m, from), ice.ErrNotFound, from) { + if m.Warn(!Exists(m, from), ice.ErrNotFound, from) { return } Remove(m, name) if MkdirAll(m, path.Dir(name)); m.Warn(Link(m, from, name)) && m.Warn(Symlink(m, from, name), ice.ErrWarn, from) { return } - m.Logs(SAVE, FILE, name, FROM, from) - m.Echo(name) + m.Logs(SAVE, FILE, name, FROM, from).Echo(name) } const ( CONTENT = "content" + OFFSET = "offset" ALIAS = "alias" FROM = "from" TO = "to" ) -const LOAD = "load" const DEFS = "defs" const SAVE = "save" const PUSH = "push" const COPY = "copy" const LINK = "link" +const LOAD = "load" func init() { Index.MergeCommands(ice.Commands{ @@ -94,44 +79,106 @@ func init() { _defs_file(m, arg[0], arg[1:]...) }}, SAVE: {Name: "save file text run", Help: "保存", Hand: func(m *ice.Message, arg ...string) { - if len(arg) == 1 { - arg = append(arg, m.Option(CONTENT)) - } + kit.If(len(arg) == 1, func() { arg = append(arg, m.Option(CONTENT)) }) _save_file(m, arg[0], arg[1:]...) }}, PUSH: {Name: "push file text run", Help: "追加", Hand: func(m *ice.Message, arg ...string) { - if len(arg) == 1 { - arg = append(arg, m.Option(CONTENT)) - } + kit.If(len(arg) == 1, func() { arg = append(arg, m.Option(CONTENT)) }) _push_file(m, arg[0], arg[1:]...) }}, COPY: {Name: "copy file from run", Help: "复制", Hand: func(m *ice.Message, arg ...string) { - for _, file := range arg[1:] { - if ExistsFile(m, file) { - _copy_file(m, arg[0], arg[1:]...) - return - } - } + kit.If(len(arg) > 1 && Exists(m, arg[1]), func() { _copy_file(m, arg[0], arg[1:]...) }) }}, LINK: {Name: "link file from run", Help: "链接", Hand: func(m *ice.Message, arg ...string) { _link_file(m, arg[0], arg[1]) }}, }) } -func Copy(m *ice.Message, cb func([]byte, int) []byte, to, from string) { - if _from, e := os.Open(from); m.Assert(e) { - defer _from.Close() - if _to, e := os.Create(to); m.Assert(e) { - defer _to.Close() +func Create(m *ice.Message, p string, cb ice.Any) { + if f, p, e := CreateFile(m, p); !m.Warn(e) { + defer f.Close() + switch cb := cb.(type) { + case func(io.Writer, string): + cb(f, p) + case func(io.Writer): + cb(f) + default: + m.ErrorNotImplement(cb) + } + } +} +func Append(m *ice.Message, p string, cb ice.Any) { + if f, p, e := AppendFile(m, p); !m.Warn(e) { + defer f.Close() + switch cb := cb.(type) { + case func(io.Writer, string): + cb(f, p) + case func(io.Writer): + cb(f) + default: + m.ErrorNotImplement(cb) + } + } +} +func Save(m *ice.Message, w io.Writer, s string, cb ice.Any) { + if n, e := fmt.Fprint(w, s); !m.Warn(e) { + switch cb := cb.(type) { + case func(int): + cb(n) + default: + m.ErrorNotImplement(cb) + } + } +} +func Copy(m *ice.Message, w io.Writer, r io.Reader, cb ice.Any) { + if n, e := io.Copy(w, r); !m.Warn(e) { + switch cb := cb.(type) { + case func(int): + cb(int(n)) + default: + m.ErrorNotImplement(cb) + } + } +} +func CopyStream(m *ice.Message, to io.WriteCloser, from io.ReadCloser, cache, total int, cb ice.Any) { + count, buf := 0, make([]byte, cache) + for { + n, e := from.Read(buf) + to.Write(buf[0:n]) + if count += n; count > total { + total = count + } + switch value := count * 100 / total; cb := cb.(type) { + case func(int, int, int): + cb(count, total, value) + case func(int, int): + cb(count, total) + case nil: + default: + m.ErrorNotImplement(cb) + } + if e == io.EOF || m.Warn(e) { + break + } + } +} +func CopyFile(m *ice.Message, to, from string, cb func([]byte, int) []byte) { + Open(m, from, func(r io.Reader) { + Create(m, to, func(w io.Writer) { offset, buf := 0, make([]byte, 1024*1024) for { - n, _ := _from.Read(buf) - if n, _ = _to.Write(cb(buf[:n], offset)); n == 0 { + n, _ := r.Read(buf) + if n, _ = w.Write(cb(buf[:n], offset)); n == 0 { break } offset += n } m.Logs(SAVE, FILE, to, FROM, from, SIZE, offset) - } - } + }) + }) +} +func Pipe(m *ice.Message, cb func(string)) io.WriteCloser { + r, w := io.Pipe() + m.Go(func() { kit.For(r, cb) }) + return w } diff --git a/base/nfs/tar.go b/base/nfs/tar.go index a4317415..39e75a5d 100644 --- a/base/nfs/tar.go +++ b/base/nfs/tar.go @@ -4,7 +4,6 @@ import ( "archive/tar" "compress/gzip" "io" - "io/ioutil" "os" "path" "strings" @@ -14,49 +13,42 @@ import ( kit "shylinux.com/x/toolkits" ) -func _tar_list(m *ice.Message, p string, cb func(*tar.Header, *tar.Reader, int)) *ice.Message { - const ( - GZ = "gz" - ) - var r io.Reader - if f, e := os.Open(p); m.Warn(e, ice.ErrNotValid, p) { - return m - } else { - defer f.Close() - r = f - } - for { - switch kit.Ext(p) { - case GZ: - if f, e := gzip.NewReader(r); m.Warn(e, ice.ErrNotValid, p) { - return m - } else { - defer f.Close() - r = f - } - p = kit.TrimExt(p, GZ) - case TAR: - i := 0 - for r := tar.NewReader(r); ; i++ { - h, e := r.Next() - if m.Warn(e) { - break +func _tar_list(m *ice.Message, p string, cb func(*tar.Header, *tar.Reader, int)) { + Open(m, p, func(r io.Reader) { + for { + switch kit.Ext(p) { + case GZ: + if f, e := gzip.NewReader(r); m.Warn(e, ice.ErrNotValid, p) { + return + } else { + defer f.Close() + r, p = f, kit.TrimExt(p, GZ) } - if h.Size == 0 { - i-- - continue + case TAR: + i := 0 + for r := tar.NewReader(r); ; i++ { + h, e := r.Next() + if m.Warn(e) { + break + } + if h.Size == 0 { + i-- + continue + } + cb(h, r, i) } - cb(h, r, i) + m.StatusTimeCount(mdb.TOTAL, i) + return + default: + return } - m.StatusTimeCount(mdb.TOTAL, i) - return m - default: - return m } - } - return m + }) } +const ( + GZ = "gz" +) const TAR = "tar" func init() { @@ -65,7 +57,7 @@ func init() { mdb.NEXT: {Hand: func(m *ice.Message, arg ...string) { mdb.PrevPage(m, arg[0], kit.Slice(arg, 1)...) }}, mdb.PREV: {Hand: func(m *ice.Message, arg ...string) { mdb.NextPageLimit(m, arg[0], kit.Slice(arg, 1)...) }}, mdb.EXPORT: {Hand: func(m *ice.Message, arg ...string) { - list, size := map[string]bool{}, int64(0) + list, size := kit.Dict(), 0 _tar_list(m, m.Option(PATH), func(h *tar.Header, r *tar.Reader, i int) { if h.Name == m.Option(FILE) || m.Option(FILE) == "" { p := path.Join(path.Dir(m.Option(PATH)), h.Name) @@ -73,22 +65,12 @@ func init() { MkdirAll(m, p) return } - if !list[path.Dir(p)] { - list[path.Dir(p)] = true - MkdirAll(m, path.Dir(p)) - } - if f, p, e := CreateFile(m, p); !m.Warn(e) { - defer f.Close() - if m.Option(FILE) != "" { - defer m.Cmdy(DIR, p, "time,path,size") - defer m.Cmdy(CAT, p) - } - if n, e := io.Copy(f, r); !m.Warn(e) { - size += n - // m.Logs(mdb.EXPORT, LINE, i, SIZE, kit.FmtSize(size), FILE, p, SIZE, kit.FmtSize(n)) - os.Chmod(p, os.FileMode(h.Mode)) - } - } + kit.IfNoKey(list, path.Dir(p), func(p string) { MkdirAll(m, p) }) + Create(m, p, func(w io.Writer) { + os.Chmod(p, os.FileMode(h.Mode)) + Copy(m, w, r, func(n int) { size += n }) + kit.If(m.Option(FILE), func() { m.Cmdy(DIR, p).Cmdy(CAT, p) }) + }) } }) }}, @@ -108,17 +90,11 @@ func init() { if i >= (page-1)*size && i < page*size { m.Push(mdb.TIME, h.ModTime.Format(ice.MOD_TIME)).Push(FILE, h.Name).Push(SIZE, kit.FmtSize(h.Size)) } - }).PushAction(mdb.EXPORT) + }) + m.PushAction(mdb.EXPORT) }}, }) } -func ReadAll(m *ice.Message, r io.Reader) []byte { - if buf, e := ioutil.ReadAll(r); m.Warn(e) { - return buf - } else { - return buf - } -} func TarExport(m *ice.Message, path string, file ...string) { m.Cmd(TAR, mdb.EXPORT, ice.Maps{PATH: path, FILE: kit.Select("", file, 0)}) } diff --git a/base/nfs/trash.go b/base/nfs/trash.go index 8bba5192..b309722c 100644 --- a/base/nfs/trash.go +++ b/base/nfs/trash.go @@ -1,6 +1,7 @@ package nfs import ( + "io" "os" "path" @@ -19,15 +20,9 @@ func _trash_create(m *ice.Message, from string) { return } p := path.Join(ice.VAR_TRASH, path.Base(from)) - if !s.IsDir() { - if f, e := OpenFile(m, from); m.Assert(e) { - defer f.Close() - p = path.Join(ice.VAR_TRASH, kit.HashsPath(f)) - } - } - if RemoveAll(m, p); !m.Warn(Rename(m, from, p)) { - mdb.HashCreate(m, FROM, from, FILE, p) - } + 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) }) } const TRASH = "trash" diff --git a/base/ssh/render.go b/base/ssh/render.go index 4779f7aa..672577ca 100644 --- a/base/ssh/render.go +++ b/base/ssh/render.go @@ -11,9 +11,7 @@ import ( func Render(msg *ice.Message, cmd string, arg ...ice.Any) (res string) { switch args := kit.Simple(arg...); cmd { case ice.RENDER_RESULT: - if len(args) > 0 { - msg.Resultv(args) - } + kit.If(len(args) > 0, func() { msg.Resultv(args) }) res = msg.Result() case ice.RENDER_VOID: return res diff --git a/base/ssh/script.go b/base/ssh/script.go index 486a1579..f87dce65 100644 --- a/base/ssh/script.go +++ b/base/ssh/script.go @@ -32,26 +32,26 @@ type Frame struct { count int } -func (f *Frame) prompt(m *ice.Message, list ...string) *Frame { +func (f *Frame) prompt(m *ice.Message, arg ...string) *Frame { if f.source != STDIO { return f } - kit.If(len(list) == 0, func() { list = append(list, f.ps1...) }) + kit.If(len(arg) == 0, func() { arg = append(arg, f.ps1...) }) fmt.Fprintf(f.stdout, kit.Select("\r", "\r\033[2K", ice.Info.Colors)) - for _, v := range list { - switch v { + kit.For(arg, func(k string) { + switch k { case mdb.COUNT: fmt.Fprintf(f.stdout, "%d", f.count) case tcp.HOSTNAME: fmt.Fprintf(f.stdout, "%s", kit.Slice(kit.Split(ice.Info.Hostname, " -/."), -1)[0]) case mdb.TIME: - fmt.Fprintf(f.stdout, time.Now().Format("15:04:05")) + fmt.Fprintf(f.stdout, kit.Slice(kit.Split(time.Now().Format(ice.MOD_TIME)), -1)[0]) case TARGET: fmt.Fprintf(f.stdout, f.target.Name) default: - kit.If(ice.Info.Colors || v[0] != '\033', func() { fmt.Fprintf(f.stdout, v) }) + kit.If(ice.Info.Colors || k[0] != '\033', func() { fmt.Fprintf(f.stdout, k) }) } - } + }) return f } func (f *Frame) printf(m *ice.Message, str string, arg ...ice.Any) *Frame { @@ -69,9 +69,7 @@ func (f *Frame) change(m *ice.Message, ls []string) []string { if ls = ls[1:]; len(target) == 0 && len(ls) > 0 { target, ls = ls[0], ls[1:] } - if target == "~" { - target = "" - } + kit.If(target == "~", func() { target = "" }) m.Spawn(f.target).Search(target+ice.PT, func(p *ice.Context, s *ice.Context) { f.target = s }) } return ls @@ -85,7 +83,6 @@ func (f *Frame) alias(m *ice.Message, ls []string) []string { return ls } func (f *Frame) parse(m *ice.Message, h, line string) string { - msg := m.Spawn(f.target) ls := kit.Split(strings.TrimSpace(line)) for i, v := range ls { if v == "#" { @@ -93,9 +90,10 @@ func (f *Frame) parse(m *ice.Message, h, line string) string { break } } - if ls = f.change(msg, f.alias(msg, ls)); len(ls) == 0 { + if ls = f.change(m, f.alias(m, ls)); len(ls) == 0 { return "" } + msg := m.Spawn(f.target) if msg.Cmdy(ls); h == STDIO && msg.IsErrNotFound() { msg.SetResult().Cmdy(cli.SYSTEM, ls) } @@ -149,9 +147,7 @@ func (f *Frame) Start(m *ice.Message, arg ...string) { m.Optionv(FRAME, f) switch f.source = kit.Select(STDIO, arg, 0); f.source { case STDIO: - if f.target == nil { - f.target = m.Target() - } + kit.If(f.target == nil, func() { f.target = m.Target() }) r, w, _ := os.Pipe() go func() { io.Copy(w, os.Stdin) }() f.pipe, f.stdin, f.stdout = w, r, os.Stdout @@ -161,7 +157,7 @@ func (f *Frame) Start(m *ice.Message, arg ...string) { if m.Option(ice.MSG_SCRIPT) != "" { ls := kit.Split(m.Option(ice.MSG_SCRIPT), ice.PS) for i := len(ls) - 1; i > 0; i-- { - if p := path.Join(path.Join(ls[:i]...), f.source); nfs.ExistsFile(m, p) { + if p := path.Join(path.Join(ls[:i]...), f.source); nfs.Exists(m, p) { f.source = p } } @@ -179,22 +175,17 @@ func (f *Frame) Start(m *ice.Message, arg ...string) { } } func (f *Frame) Close(m *ice.Message, arg ...string) { - if stdin, ok := f.stdin.(io.Closer); ok { - stdin.Close() - } + nfs.Close(m, f.stdin) f.stdin = nil } -func (f *Frame) Spawn(m *ice.Message, c *ice.Context, arg ...string) ice.Server { - return &Frame{} -} +func (f *Frame) Spawn(m *ice.Message, c *ice.Context, arg ...string) ice.Server { return &Frame{} } const ( - MESSAGE = "message" - SHELL = "shell" - FRAME = "frame" - STDIO = "stdio" - PS1 = "PS1" - PS2 = "PS2" + FRAME = "frame" + SHELL = "shell" + STDIO = "stdio" + PS1 = "PS1" + PS2 = "PS2" ) const ( SOURCE = "source" @@ -207,11 +198,6 @@ const ( func init() { Index.MergeCommands(ice.Commands{ - SHELL: {Name: "shell", Help: "交互命令", Actions: mdb.HashAction(), Hand: func(m *ice.Message, arg ...string) { - if f, ok := m.Target().Server().(*Frame); ok { - f.Spawn(m, m.Target()).Start(m, arg...) - } - }}, SOURCE: {Name: "source file run", Help: "脚本解析", Actions: mdb.HashAction(), Hand: func(m *ice.Message, arg ...string) { if f, ok := m.Target().Server().(*Frame); ok { f.Spawn(m, m.Target()).Start(m, arg...) diff --git a/base/tcp/broad.go b/base/tcp/broad.go index 59ea92a7..f3bc22b2 100644 --- a/base/tcp/broad.go +++ b/base/tcp/broad.go @@ -11,9 +11,7 @@ import ( func _server_udp(m *ice.Message, arg ...string) { l, e := net.ListenUDP(UDP4, UDPAddr(m, "0.0.0.0", m.Option(PORT))) - if e == nil { - defer l.Close() - } + defer kit.If(e == nil, func() { l.Close() }) mdb.HashCreate(m, arg, kit.Dict(mdb.TARGET, l), STATUS, kit.Select(ERROR, OPEN, e == nil), ERROR, kit.Format(e)) switch cb := m.OptionCB("").(type) { case func(*net.UDPAddr, []byte): @@ -26,17 +24,18 @@ func _server_udp(m *ice.Message, arg ...string) { break } } + default: + m.ErrorNotImplement(cb) } } func _client_dial_udp4(m *ice.Message, arg ...string) { c, e := net.DialUDP(UDP4, nil, UDPAddr(m, kit.Select("255.255.255.255", m.Option(HOST)), m.Option(PORT))) - if e == nil { - defer c.Close() - } + defer kit.If(e == nil, func() { c.Close() }) switch cb := m.OptionCB("").(type) { case func(*net.UDPConn): - m.Assert(e) - cb(c) + kit.If(!m.Warn(e), func() { cb(c) }) + default: + m.ErrorNotImplement(cb) } } diff --git a/base/tcp/client.go b/base/tcp/client.go index f087c514..979a6601 100644 --- a/base/tcp/client.go +++ b/base/tcp/client.go @@ -30,9 +30,7 @@ func (c *Conn) Close() error { return c.Conn.Close() } func _client_dial(m *ice.Message, arg ...string) { c, e := net.Dial(TCP, m.Option(HOST)+ice.DF+m.Option(PORT)) c = &Conn{Conn: c, m: m, s: &Stat{}} - if e == nil { - defer c.Close() - } + defer kit.If(e == nil, func() { c.Close() }) switch cb := m.OptionCB("").(type) { case func(net.Conn): kit.If(!m.Warn(e), func() { cb(c) }) diff --git a/base/tcp/host.go b/base/tcp/host.go index 4494d374..1210dcfe 100644 --- a/base/tcp/host.go +++ b/base/tcp/host.go @@ -22,24 +22,15 @@ func _host_list(m *ice.Message, name string) { if strings.Contains(ip[0], ice.DF) || len(ip) == 0 { continue } - m.Push(mdb.INDEX, v.Index) - m.Push(mdb.NAME, v.Name) - m.Push(aaa.IP, ip[0]) - m.Push("mask", ip[1]) - m.Push("hard", v.HardwareAddr.String()) + m.Push(mdb.INDEX, v.Index).Push(mdb.NAME, v.Name).Push(aaa.IP, ip[0]).Push("mask", ip[1]).Push("hard", v.HardwareAddr.String()) } } } } if len(m.Appendv(aaa.IP)) == 0 { - m.Push(mdb.INDEX, -1) - m.Push(mdb.NAME, LOCALHOST) - m.Push(aaa.IP, "127.0.0.1") - m.Push("mask", "255.0.0.0") - m.Push("hard", "") + m.Push(mdb.INDEX, -1).Push(mdb.NAME, LOCALHOST).Push(aaa.IP, "127.0.0.1").Push("mask", "255.0.0.0").Push("hard", "") } - m.SortInt(mdb.INDEX) - m.StatusTimeCount() + m.SortInt(mdb.INDEX).StatusTimeCount() } const ( @@ -65,7 +56,7 @@ func init() { }}, mdb.SEARCH: {Hand: func(m *ice.Message, arg ...string) { if arg[0] == mdb.FOREACH && arg[1] == "" { - ip := m.Cmd("", GATEWAY).Append(aaa.IP) + ip := m.Cmdv("", GATEWAY, aaa.IP) m.PushSearch(mdb.TYPE, GATEWAY, mdb.NAME, ip, mdb.TEXT, "http://"+ip) } }}, @@ -78,14 +69,14 @@ func init() { }}, PUBLISH: {Hand: func(m *ice.Message, arg ...string) { if strings.Contains(arg[0], LOCALHOST) { - arg[0] = strings.Replace(arg[0], LOCALHOST, m.Cmd("").Append(aaa.IP), 1) + arg[0] = strings.Replace(arg[0], LOCALHOST, m.Cmdv(HOST, aaa.IP), 1) } else if strings.Contains(arg[0], "127.0.0.1") { - arg[0] = strings.Replace(arg[0], "127.0.0.1", m.Cmd("").Append(aaa.IP), 1) + arg[0] = strings.Replace(arg[0], "127.0.0.1", m.Cmdv(HOST, aaa.IP), 1) } m.Echo(arg[0]) }}, GATEWAY: {Hand: func(m *ice.Message, arg ...string) { - m.Push(aaa.IP, kit.Keys(kit.Slice(strings.Split(m.Cmd("").Append(aaa.IP), ice.PT), 0, 3), "1")) + m.Push(aaa.IP, kit.Keys(kit.Slice(strings.Split(m.Cmdv("", aaa.IP), ice.PT), 0, 3), "1")) }}, }, mdb.HashAction(mdb.SHORT, mdb.TEXT), mdb.ClearOnExitHashAction()), Hand: func(m *ice.Message, arg ...string) { _host_list(m, kit.Select("", arg, 0)) diff --git a/base/tcp/peek.go b/base/tcp/peek.go index 3d7a1341..de59d605 100644 --- a/base/tcp/peek.go +++ b/base/tcp/peek.go @@ -37,7 +37,7 @@ func (s PeekConn) Peek(n int) (res []byte) { return b[:_n] } func (s PeekConn) IsHTTP() bool { - if bytes.Equal(s.Peek(4), []byte("GET ")) { + if head := s.Peek(4); bytes.Equal(head, []byte("GET ")) { return true } return false @@ -45,10 +45,8 @@ func (s PeekConn) IsHTTP() bool { func (s PeekConn) Redirect(status int, location string) { DF, NL := ": ", "\r\n" s.Conn.Write([]byte(strings.Join([]string{ - kit.Format("HTTP/1.1 %d %s", status, http.StatusText(status)), kit.JoinKV(DF, NL, - "Location", location, "Content-Length", "0", - )}, NL) + NL + NL)) -} -func NewPeekConn(c net.Conn) PeekConn { - return PeekConn{Conn: c, Buf: &Buf{}} + kit.Format("HTTP/1.1 %d %s", status, http.StatusText(status)), + kit.JoinKV(DF, NL, "Location", location, "Content-Length", "0"), + }, NL) + NL + NL)) } +func NewPeekConn(c net.Conn) PeekConn { return PeekConn{Conn: c, Buf: &Buf{}} } diff --git a/base/tcp/port.go b/base/tcp/port.go index 1cfa92fc..22b4b872 100644 --- a/base/tcp/port.go +++ b/base/tcp/port.go @@ -15,11 +15,9 @@ import ( func _port_right(m *ice.Message, arg ...string) string { current, end := kit.Int(kit.Select(mdb.Config(m, CURRENT), arg, 0)), kit.Int(mdb.Config(m, END)) - if current >= end { - current = kit.Int(mdb.Config(m, BEGIN)) - } + kit.If(current >= end, func() { current = kit.Int(mdb.Config(m, BEGIN)) }) for i := current; i < end; i++ { - if p := path.Join(ice.USR_LOCAL_DAEMON, kit.Format(i)); nfs.ExistsFile(m, p) { + if p := path.Join(ice.USR_LOCAL_DAEMON, kit.Format(i)); nfs.Exists(m, p) { } else if c, e := net.Dial(TCP, kit.Format(":%d", i)); e == nil { m.Info("port exists %v", i) @@ -56,21 +54,15 @@ func init() { return } current := kit.Int(mdb.Config(m, BEGIN)) - m.Option(nfs.DIR_ROOT, ice.USR_LOCAL_DAEMON) - m.Cmd(nfs.DIR, nfs.PWD, func(value ice.Maps) { - bin := m.CmdAppend(nfs.DIR, path.Join(value[nfs.PATH], ice.BIN), nfs.PATH) - if bin == "" { - bin = m.CmdAppend(nfs.DIR, path.Join(value[nfs.PATH], "sbin"), nfs.PATH) - } + m.Options(nfs.DIR_ROOT, ice.USR_LOCAL_DAEMON).Cmd(nfs.DIR, nfs.PWD, func(value ice.Maps) { + bin := m.Cmdv(nfs.DIR, path.Join(value[nfs.PATH], ice.BIN), nfs.PATH) + kit.If(bin == "", func() { bin = m.Cmdv(nfs.DIR, path.Join(value[nfs.PATH], "sbin"), nfs.PATH) }) port := kit.Int(path.Base(value[nfs.PATH])) - m.Push(mdb.TIME, value[mdb.TIME]) - m.Push(PORT, port) - m.Push(nfs.SIZE, value[nfs.SIZE]) - m.Push(ice.BIN, strings.TrimPrefix(bin, value[nfs.PATH])) + m.Push(mdb.TIME, value[mdb.TIME]).Push(PORT, port).Push(nfs.SIZE, value[nfs.SIZE]).Push(ice.BIN, strings.TrimPrefix(bin, value[nfs.PATH])) current = kit.Max(current, port) }) - mdb.Config(m, CURRENT, current) m.PushAction(nfs.TRASH).StatusTimeCount(ctx.ConfigSimple(m, BEGIN, CURRENT, END)).SortInt(PORT) + mdb.Config(m, CURRENT, current) }}, }) } diff --git a/base/tcp/server.go b/base/tcp/server.go index c9b92888..dc498fd2 100644 --- a/base/tcp/server.go +++ b/base/tcp/server.go @@ -30,14 +30,13 @@ func (l Listener) Close() error { func _server_listen(m *ice.Message, arg ...string) { l, e := net.Listen(TCP, m.Option(HOST)+ice.DF+m.Option(PORT)) l = &Listener{Listener: l, m: m, h: mdb.HashCreate(m, arg, kit.Dict(mdb.TARGET, l), STATUS, kit.Select(ERROR, OPEN, e == nil), ERROR, kit.Format(e)), s: &Stat{}} - if e == nil { - defer l.Close() - } + defer kit.If(e == nil, func() { l.Close() }) switch cb := m.OptionCB("").(type) { case func(net.Listener): m.Assert(e) cb(l) case func(net.Conn): + m.Assert(e) for { if c, e := l.Accept(); !m.Warn(e) { cb(c) diff --git a/base/tcp/tcp.go b/base/tcp/tcp.go index 9a909e40..0ee7c597 100644 --- a/base/tcp/tcp.go +++ b/base/tcp/tcp.go @@ -1,8 +1,6 @@ package tcp -import ( - ice "shylinux.com/x/icebergs" -) +import ice "shylinux.com/x/icebergs" const TCP = "tcp" diff --git a/base/web/cache.go b/base/web/cache.go index f5f81dfa..0cf27348 100644 --- a/base/web/cache.go +++ b/base/web/cache.go @@ -74,7 +74,7 @@ func _cache_download(m *ice.Message, r *http.Response, file string, cb ice.Any) if f, p, e := miss.CreateFile(file); !m.Warn(e, ice.ErrNotValid, DOWNLOAD) { defer f.Close() last, base := 0, 10 - nfs.CopyFile(m, f, r.Body, base*ice.MOD_BUFS, kit.Int(kit.Select("100", r.Header.Get(ContentLength))), func(count, total, value int) { + nfs.CopyStream(m, f, r.Body, base*ice.MOD_BUFS, kit.Int(kit.Select("100", r.Header.Get(ContentLength))), func(count, total, value int) { if value/base == last { return } diff --git a/base/web/dream.go b/base/web/dream.go index 6c94caf9..b771dd3a 100644 --- a/base/web/dream.go +++ b/base/web/dream.go @@ -41,7 +41,7 @@ func _dream_show(m *ice.Message, name string) { kit.If(!strings.Contains(name, "-") || !strings.HasPrefix(name, "20"), func() { name = m.Time("20060102-") + name }) defer m.ProcessOpen(m.MergePod(m.Option(mdb.NAME, name))) p := path.Join(ice.USR_LOCAL_WORK, name) - if pid := m.Cmdx(nfs.CAT, path.Join(p, ice.Info.PidPath), kit.Dict(ice.MSG_USERROLE, aaa.TECH)); pid != "" && nfs.ExistsFile(m, "/proc/"+pid) { + if pid := m.Cmdx(nfs.CAT, path.Join(p, ice.Info.PidPath), kit.Dict(ice.MSG_USERROLE, aaa.TECH)); pid != "" && nfs.Exists(m, "/proc/"+pid) { m.Info("already exists %v", pid) return } else if m.Cmd(SPACE, name).Length() > 0 { @@ -65,7 +65,7 @@ func _dream_template(m *ice.Message, p 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, }, func(file string) { - if nfs.ExistsFile(m, path.Join(p, file)) { + if nfs.Exists(m, path.Join(p, file)) { return } switch m.Cmdy(nfs.COPY, path.Join(p, file), path.Join(ice.USR_LOCAL_WORK, m.Option(nfs.TEMPLATE), file)); file { diff --git a/base/web/serve.go b/base/web/serve.go index db04422c..f23fb748 100644 --- a/base/web/serve.go +++ b/base/web/serve.go @@ -26,7 +26,6 @@ func _serve_start(m *ice.Message) { kit.If(cli.IsWindows(), func() { m.Cmd(SPIDE, ice.OPS, _serve_address(m)+"/exit").Sleep30ms() }) cli.NodeInfo(m, kit.Select(ice.Info.Hostname, m.Option(tcp.NODENAME)), SERVER) m.Start("", m.OptionSimple(tcp.HOST, tcp.PORT)...) - // m.Target().Start(m, m.OptionSimple(tcp.HOST, tcp.PORT)...) } func _serve_main(m *ice.Message, w http.ResponseWriter, r *http.Request) bool { const ( @@ -54,7 +53,7 @@ func _serve_main(m *ice.Message, w http.ResponseWriter, r *http.Request) bool { if m.Logs(r.Header.Get(ice.MSG_USERIP), r.Method, r.URL.String()); r.Method == http.MethodGet { if msg := m.Spawn(w, r).Options(ice.MSG_USERUA, r.UserAgent()); path.Join(r.URL.Path) == ice.PS { return !Render(RenderMain(msg), msg.Option(ice.MSG_OUTPUT), kit.List(msg.Optionv(ice.MSG_ARGS))...) - } else if p := path.Join(kit.Select(ice.USR_VOLCANOS, ice.USR_INTSHELL, msg.IsCliUA()), r.URL.Path); nfs.ExistsFile(msg, p) { + } else if p := path.Join(kit.Select(ice.USR_VOLCANOS, ice.USR_INTSHELL, msg.IsCliUA()), r.URL.Path); nfs.Exists(msg, p) { return !Render(msg, ice.RENDER_DOWNLOAD, p) } } @@ -79,6 +78,7 @@ func _serve_handle(key string, cmd *ice.Command, m *ice.Message, w http.Response default: r.ParseMultipartForm(kit.Int64(kit.Select("4096", r.Header.Get(ContentLength)))) kit.For(r.PostForm, func(k string, v []string) { _log(FORM, k, kit.Join(v, ice.SP)).Optionv(k, v) }) + kit.For(r.PostForm, func(k string, v []string) { _log(FORM, k, kit.Join(v, ice.SP)).Optionv(k, v) }) } kit.For(r.Cookies(), func(k, v string) { m.Optionv(k, v) }) m.OptionDefault(ice.MSG_HEIGHT, "480", ice.MSG_WIDTH, "320") diff --git a/conf.go b/conf.go index ca679b0a..52ae578e 100644 --- a/conf.go +++ b/conf.go @@ -1,5 +1,7 @@ package ice +import kit "shylinux.com/x/toolkits" + const ( TB = "\t" SP = " " @@ -45,12 +47,6 @@ const ( RES = "res" ERR = "err" ) -const ( // MOD - MOD_DIR = 0750 - MOD_FILE = 0640 - MOD_BUFS = 4096 - MOD_TIME = "2006-01-02 15:04:05" -) const ( // REPOS CONTEXTS = "contexts" INTSHELL = "intshell" @@ -64,6 +60,15 @@ const ( // REPOS PUBLISH = "publish" RELEASE = "release" ) +const ( // MOD + MOD_DIR = 0750 + MOD_FILE = 0640 + MOD_BUFS = 4096 + MOD_DATE = kit.MOD_DATE + MOD_TIME = kit.MOD_TIME + MOD_TIMES = kit.MOD_TIMES +) + const ( // DIR SRC = "src" ETC = "etc" diff --git a/core/chat/action.go b/core/chat/action.go index 0c54cdbc..313a1a20 100644 --- a/core/chat/action.go +++ b/core/chat/action.go @@ -62,6 +62,9 @@ func _action_share(m *ice.Message, arg ...string) { } } +const ( + THEME = "theme" +) const ACTION = "action" func init() { diff --git a/core/chat/chat.shy b/core/chat/chat.shy index 549ef0df..59f45822 100644 --- a/core/chat/chat.shy +++ b/core/chat/chat.shy @@ -1,25 +1,21 @@ -chat.go -chat.shy header.go +action.go footer.go search.go -action.go river.go storm.go +favor.go grant.go sso.go pod.go cmd.go +chat.go +chat.shy -favor.go +trans.go iframe.go keyboard.go location.go location.shy - -div.go -theme.go -website.go template.go -trans.go oauth diff --git a/core/chat/cmd.go b/core/chat/cmd.go index b54bb58e..5449799a 100644 --- a/core/chat/cmd.go +++ b/core/chat/cmd.go @@ -23,7 +23,7 @@ func _cmd_file(m *ice.Message, arg ...string) bool { ctx.DisplayBase(m, ctx.FileURI(p)) web.RenderCmd(m, kit.Select(ice.CAN_PLUGIN, ctx.GetFileCmd(p))) default: - if p = strings.TrimPrefix(p, ice.SRC+ice.PS); nfs.ExistsFile(m, path.Join(ice.SRC, p)) { + if p = strings.TrimPrefix(p, ice.SRC+ice.PS); nfs.Exists(m, path.Join(ice.SRC, p)) { if msg := m.Cmd(mdb.ENGINE, kit.Ext(p)); msg.Length() > 0 { m.Cmdy(mdb.ENGINE, kit.Ext(p), p, ice.SRC+ice.PS).RenderResult() break diff --git a/core/chat/div.go b/core/chat/div.go deleted file mode 100644 index ee2780f3..00000000 --- a/core/chat/div.go +++ /dev/null @@ -1,109 +0,0 @@ -package chat - -import ( - "path" - "strings" - - ice "shylinux.com/x/icebergs" - "shylinux.com/x/icebergs/base/ctx" - "shylinux.com/x/icebergs/base/lex" - "shylinux.com/x/icebergs/base/mdb" - "shylinux.com/x/icebergs/base/nfs" - "shylinux.com/x/icebergs/base/web" - kit "shylinux.com/x/toolkits" -) - -func _div_parse(m *ice.Message, text string) string { - return m.Cmdx(lex.SPLIT, "", ctx.INDEX, ctx.ARGS, kit.Dict(nfs.CAT_CONTENT, text), func(deep int, ls []string) []string { - if ls[0] == DIV { - ls = append([]string{"", "", ctx.STYLE, kit.Select(DIV, ls, 1)}, kit.Slice(ls, 2)...) - } - return ls - }) -} - -const DIV = "div" - -func init() { - Index.MergeCommands(ice.Commands{ - web.PP(DIV): {Name: "/div/", Help: "定制", Actions: ice.MergeActions(ctx.CmdAction()), Hand: func(m *ice.Message, arg ...string) { - switch p := path.Join(arg...); kit.Ext(kit.Select("", p)) { - case nfs.HTML: - m.RenderDownload(p) - case nfs.CSS: - m.RenderResult(_div_template, m.Cmdx(nfs.CAT, p), m.Cmdx(nfs.CAT, strings.Replace(p, ".css", ".js", -1))) - case nfs.JS: - m.RenderResult(_div_template, m.Cmdx(nfs.CAT, strings.Replace(p, ".js", ".css", -1)), m.Cmdx(nfs.CAT, p)) - case nfs.JSON: - m.RenderResult(_div_template2, kit.Format(kit.UnMarshal(m.Cmdx(nfs.CAT, p)))) - default: - web.RenderCmd(m, m.PrefixKey(), p) - } - }}, - DIV: {Name: "div hash auto import", Help: "定制", Actions: ice.MergeActions(ice.Actions{ - mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) { - switch arg[0] { - case nfs.PATH: - m.Cmdy(nfs.DIR, arg[1:]).ProcessAgain() - case ctx.INDEX: - m.OptionFields(mdb.INDEX) - m.Cmdy(ctx.COMMAND, mdb.SEARCH, ctx.COMMAND, "", "") - case ctx.STYLE: - m.Push(arg[0], "div") - m.Push(arg[0], "span") - m.Push(arg[0], "output") - } - }}, - mdb.CREATE: {Name: "create type=page name=hi text"}, - lex.SPLIT: {Name: "split name=hi text", Help: "生成", Hand: func(m *ice.Message, arg ...string) { - m.ProcessRewrite(mdb.HASH, m.Cmdx(DIV, mdb.CREATE, m.OptionSimple(mdb.NAME), mdb.TEXT, _div_parse(m, m.Option(mdb.TEXT)))) - }}, - }, mdb.HashAction(mdb.FIELD, "time,hash,type,name,text", nfs.PATH, ice.USR_PUBLISH, nfs.TEMPLATE, _div_template), ctx.CmdAction()), Hand: func(m *ice.Message, arg ...string) { - switch kit.Ext(kit.Select("", arg, 0)) { - case nfs.SHY: - m.Fields(0) - m.Push(mdb.TEXT, _div_parse(m, m.Cmdx(nfs.CAT, arg[0]))) - ctx.DisplayLocal(m, "") - default: - if mdb.HashSelect(m, arg...); len(arg) > 0 { - m.StatusTime(mdb.LINK, web.MergeURL2(m, "/chat/div/"+arg[0])).Action("添加", "保存") - ctx.DisplayLocal(m, "") - } else { - m.Action(lex.SPLIT, mdb.CREATE) - } - } - }}, - }) -} - -var _div_template = ` - - - - volcanos - - - - - - - - - - -` -var _div_template2 = ` - - - - volcanos - - - - - - - - - -` diff --git a/core/chat/pod.go b/core/chat/pod.go index 13631c00..b9ab0a39 100644 --- a/core/chat/pod.go +++ b/core/chat/pod.go @@ -25,7 +25,7 @@ func init() { if len(arg) == 0 || kit.Select("", arg, 0) == "" { web.RenderCmd(m, web.SPACE) } else if len(arg) == 1 { - if m.Cmd(web.SPACE, arg[0]).Length() == 0 && nfs.ExistsFile(m, path.Join(ice.USR_LOCAL_WORK, arg[0])) { + 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])) } web.RenderMain(m) diff --git a/core/chat/theme.go b/core/chat/theme.go deleted file mode 100644 index e6575eb1..00000000 --- a/core/chat/theme.go +++ /dev/null @@ -1,143 +0,0 @@ -package chat - -import ( - "path" - - ice "shylinux.com/x/icebergs" - "shylinux.com/x/icebergs/base/aaa" - "shylinux.com/x/icebergs/base/mdb" - "shylinux.com/x/icebergs/base/nfs" - "shylinux.com/x/icebergs/base/web" - kit "shylinux.com/x/toolkits" -) - -const THEME = "theme" - -func init() { - form := ice.Map{ - "body.background": ice.Map{mdb.TYPE: "text", mdb.NAME: "background", mdb.VALUE: "black"}, - "header.height": ice.Map{"tags": "panel.Header,panel.Header>div.output", mdb.TYPE: "text", mdb.NAME: "height", mdb.VALUE: "31"}, - } - Index.MergeCommands(ice.Commands{ - THEME: {Name: "theme zone id auto create insert", Help: "主题", Actions: ice.MergeActions(ice.Actions{ - mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) { - switch arg[0] { - case "tags": - for k := range form { - m.Push(arg[0], k) - } - case "type": - m.Push(arg[0], "text") - m.Push(arg[0], "textarea") - m.Push(arg[0], "select") - case "name", "value": - if tags, ok := form[m.Option("tags")]; ok { - m.Push(arg[0], kit.Format(kit.Value(tags, arg[0]))) - } else if arg[0] == "name" { - m.Push(arg[0], "background-color") - m.Push(arg[0], "color") - } - default: - m.Push(arg[0], "red") - m.Push(arg[0], "blue") - m.Push(arg[0], "yellow") - m.Push(arg[0], "green") - m.Push(arg[0], "blue") - m.Push(arg[0], "cyan") - m.Push(arg[0], "magenta") - m.Push(arg[0], "white") - m.Push(arg[0], "black") - } - m.Cmdy(mdb.INPUTS, m.PrefixKey(), "", mdb.ZONE, arg) - }}, - "create": {Name: "create theme=demo hover=gray float=lightgray color=black background=white", Hand: func(m *ice.Message, arg ...string) { - m.Cmd(nfs.SAVE, path.Join("src/website/theme/"+m.Option("theme")+".css"), kit.Renders(_theme_template, m)) - }}, - "form": {Name: "form", Help: "表单", Hand: func(m *ice.Message, arg ...string) { - m.Cmd(m.CommandKey(), m.Option(mdb.ZONE), func(value ice.Maps) { - tags, _ := form[value["tags"]] - m.Push("tags", value["tags"]) - m.Push("type", kit.Select(kit.Format(kit.Value(tags, "type")), value["type"])) - m.Push("name", kit.Select(kit.Format(kit.Value(tags, "name")), value["name"])) - m.Push("value", kit.Select(kit.Format(kit.Value(tags, "value")), value["value"])) - }) - kit.For(form, func(k string, v ice.Map) { - m.Push("tags", k) - m.Push("", v, kit.Split("type,name,value")) - }) - m.EchoButton("submit") - }}, - "submit": {Name: "form zone", Help: "提交", Hand: func(m *ice.Message, arg ...string) { - m.Echo("done") - }}, - "choose": {Name: "choose", Help: "切换", Hand: func(m *ice.Message, arg ...string) { - m.ProcessLocation(web.MergeURL2(m, "", "theme", kit.TrimExt(m.Option(mdb.ZONE), nfs.CSS))) - }}, - }, mdb.ZoneAction(mdb.FIELD, "time,id,tags,type,name,value"), aaa.WhiteAction()), Hand: func(m *ice.Message, arg ...string) { - if mdb.ZoneSelect(m, arg...); len(arg) == 0 { - m.Cmd(nfs.DIR, nfs.PWD, ice.OptionFields(), kit.Dict(nfs.DIR_ROOT, "src/website/theme/")).RenameAppend(nfs.PATH, mdb.ZONE, nfs.SIZE, mdb.COUNT).Table(func(value ice.Maps) { - m.Push("", value) - }) - m.PushAction("choose", "form", mdb.REMOVE) - } else { - if p := "src/website/theme/" + arg[0]; nfs.ExistsFile(m, p) { - m.Cmdy(nfs.CAT, p) - } else { - m.Table(func(value ice.Maps) { - m.Echo("body.%s %s { %s:%s }\n", arg[0], value["tag"], value[mdb.NAME], value[mdb.VALUE]) - }) - } - } - }}, - web.PP(THEME): {Name: "/theme/", Help: "主题", Hand: func(m *ice.Message, arg ...string) { - if p := "src/website/theme/" + arg[0]; nfs.ExistsFile(m, p) { - m.RenderDownload(p) - return - } - m.Cmdy("", kit.TrimExt(kit.Select(web.BLACK, arg, 0), nfs.CSS)).RenderResult().W.Header()[web.ContentType] = kit.Simple(web.ContentCSS) - }}, - }) -} - -var _theme_template = ` -body.{{.Option "theme"}} { background-color:{{.Option "background" }}; color:{{.Option "color" }}; } -body.{{.Option "theme"}} legend { background-color:{{.Option "hover" }}; color:{{.Option "color" }}; } -body.{{.Option "theme"}} select { background-color:{{.Option "background" }}; color:{{.Option "color" }}; } -body.{{.Option "theme"}} textarea { background-color:{{.Option "background" }}; } -body.{{.Option "theme"}} input[type=text] { background-color:{{.Option "background" }}; } -body.{{.Option "theme"}} input[type=button] { background-color:{{.Option "float" }}; color:{{.Option "color" }}; } -legend, select, textarea, input[type=text], div.code, div.story[data-type=spark] { box-shadow:4px 4px 20px 4px {{.Option "float" }}; } - -body.{{.Option "theme"}} div.carte { background-color:{{.Option "float" }}; } -body.{{.Option "theme"}} div.input { background-color:{{.Option "float" }}; } -body.{{.Option "theme"}} div.story[data-type=spark] { background:{{.Option "float" }}; } -body.{{.Option "theme"}} fieldset.input { background-color:{{.Option "float" }}; } - -body.{{.Option "theme"}} table.content tr { background-color:{{.Option "background" }}; } -body.{{.Option "theme"}} table.content th { background-color:{{.Option "float" }}; } -body.{{.Option "theme"}} table.content.action th:last-child { background-color:{{.Option "float" }}; } -body.{{.Option "theme"}} table.content.action td:last-child { background-color:{{.Option "float" }}; } - -body.{{.Option "theme"}} fieldset.panel.Action { background-color:{{.Option "background" }}; } -body.{{.Option "theme"}} fieldset.panel.Footer>div.output div.toast { background-color:{{.Option "float" }}; } -body.{{.Option "theme"}} fieldset.plugin { background-color:{{.Option "background" }}; } -body.{{.Option "theme"}} fieldset.plugin { box-shadow:2px 2px 10px 4px {{.Option "float" }}; } -body.{{.Option "theme"}} fieldset.story { box-shadow:4px 4px 10px 1px {{.Option "float" }}; } -body.{{.Option "theme"}} fieldset.draw div.output { background:{{.Option "background" }}; } -body.{{.Option "theme"}} fieldset.draw div.output div.content svg { background:{{.Option "float" }}; } - -body.{{.Option "theme"}} input[type=text]:hover { background-color:{{.Option "float" }}; } -body.{{.Option "theme"}} input[type=button]:hover { background-color:{{.Option "hover" }}; } -body.{{.Option "theme"}} div.item:hover { background-color:{{.Option "float" }}; } -body.{{.Option "theme"}} div.item.select { background-color:{{.Option "float" }}; } -body.{{.Option "theme"}} div.list div.item:hover { background-color:{{.Option "hover" }}; } -body.{{.Option "theme"}} div.list div.item.select { background-color:{{.Option "hover" }}; } -body.{{.Option "theme"}} div.carte div.item:hover { background-color:{{.Option "hover" }}; } -body.{{.Option "theme"}} table.content tr:hover { background-color:{{.Option "float" }}; } -body.{{.Option "theme"}} table.content th:hover { background-color:{{.Option "hover" }}; } -body.{{.Option "theme"}} table.content td:hover { background-color:{{.Option "hover" }}; } -body.{{.Option "theme"}} table.content td.select { background-color:{{.Option "hover" }}; } -body.{{.Option "theme"}} fieldset.plugin:hover { box-shadow:12px 12px 12px 6px {{.Option "float" }}; } -body.{{.Option "theme"}} fieldset.story:hover { box-shadow:12px 12px 12px 6px {{.Option "float" }}; } -body.{{.Option "theme"}} fieldset.panel.Header>div.output div:hover { background-color:{{.Option "float" }}; } -` diff --git a/core/chat/website.go b/core/chat/website.go deleted file mode 100644 index 5c2cd9a8..00000000 --- a/core/chat/website.go +++ /dev/null @@ -1 +0,0 @@ -package chat diff --git a/core/code/autogen.go b/core/code/autogen.go index c95047eb..d205b4e2 100644 --- a/core/code/autogen.go +++ b/core/code/autogen.go @@ -51,7 +51,7 @@ func _autogen_import(m *ice.Message, main string, ctx string, mod string) { m.Cmd(cli.SYSTEM, "goimports", "-w", main) } func _autogen_version(m *ice.Message) string { - if mod := _autogen_mod(m, ice.GO_MOD); !nfs.ExistsFile(m, ".git") { + if mod := _autogen_mod(m, ice.GO_MOD); !nfs.Exists(m, ".git") { m.Cmd(REPOS, mdb.CREATE, nfs.ORIGIN, "https://"+mod, mdb.NAME, path.Base(mod), nfs.PATH, nfs.PWD) } m.Cmd(nfs.DEFS, ".gitignore", nfs.Template(m, "gitignore")) @@ -123,11 +123,11 @@ func init() { m.Option(nfs.FILE, path.Join(m.Option(mdb.ZONE), kit.Keys(m.Option(mdb.NAME), GO))) m.Option(mdb.TEXT, kit.Format("`name:\"list %s\" help:\"%s\"`", _autogen_list(m), m.Option(mdb.HELP))) defer _autogen_version(m.Spawn()) - if p := path.Join(ice.SRC, kit.ExtChange(m.Option(nfs.FILE), SHY)); !nfs.ExistsFile(m, p) { + if p := path.Join(ice.SRC, kit.ExtChange(m.Option(nfs.FILE), SHY)); !nfs.Exists(m, p) { _autogen_source(m, kit.ExtChange(path.Join(ice.SRC, m.Option(cli.MAIN)), SHY), p) _autogen_script(m, p) } - if p := path.Join(ice.SRC, m.Option(nfs.FILE)); !nfs.ExistsFile(m, p) { + if p := path.Join(ice.SRC, m.Option(nfs.FILE)); !nfs.Exists(m, p) { _autogen_import(m, path.Join(ice.SRC, m.Option(cli.MAIN)), m.Option(mdb.ZONE), _autogen_mod(m, ice.GO_MOD)) _autogen_module(m, p) } @@ -139,11 +139,11 @@ func init() { USR_RELEASE_CONF_GO = "usr/release/conf.go" USR_RELEASE_BINPACK_GO = "usr/release/binpack.go" ) - if m.Cmd(BINPACK, mdb.CREATE); nfs.ExistsFile(m, ice.USR_RELEASE) && m.Option(ice.MSG_USERPOD) == "" { - nfs.Copy(m, func(buf []byte, offset int) []byte { + if m.Cmd(BINPACK, mdb.CREATE); nfs.Exists(m, ice.USR_RELEASE) && m.Option(ice.MSG_USERPOD) == "" { + nfs.CopyFile(m, USR_RELEASE_BINPACK_GO, ice.SRC_BINPACK_GO, func(buf []byte, offset int) []byte { kit.If(offset == 0, func() { buf = bytes.Replace(buf, []byte("package main"), []byte("package ice"), 1) }) return buf - }, USR_RELEASE_BINPACK_GO, ice.SRC_BINPACK_GO) + }) m.Cmd(nfs.COPY, USR_RELEASE_CONF_GO, ice.USR_ICEBERGS+"conf.go") m.Cmdy(nfs.DIR, USR_RELEASE_BINPACK_GO) m.Cmdy(nfs.DIR, USR_RELEASE_CONF_GO) diff --git a/core/code/c.go b/core/code/c.go index 1e22cb16..12b45865 100644 --- a/core/code/c.go +++ b/core/code/c.go @@ -27,7 +27,7 @@ func _c_exec(m *ice.Message, arg ...string) { } } func _c_tags(m *ice.Message, cmd ...string) { - if !nfs.ExistsFile(m, path.Join(m.Option(nfs.PATH), nfs.TAGS)) { + if !nfs.Exists(m, path.Join(m.Option(nfs.PATH), nfs.TAGS)) { m.Cmd(cli.SYSTEM, cmd, kit.Dict(cli.CMD_DIR, m.Option(nfs.PATH))) } _inner_tags(m, m.Option(nfs.PATH), m.Option(mdb.NAME)) diff --git a/core/code/install.go b/core/code/install.go index cc5d0c32..ee774951 100644 --- a/core/code/install.go +++ b/core/code/install.go @@ -19,9 +19,9 @@ import ( func _install_path(m *ice.Message, link string) string { u := kit.ParseURL(kit.Select(m.Option(web.LINK), link)) - if p := path.Join(ice.USR_INSTALL, kit.TrimExt(u.Path)); nfs.ExistsFile(m, p) { + if p := path.Join(ice.USR_INSTALL, kit.TrimExt(u.Path)); nfs.Exists(m, p) { return p - } else if pp := path.Join(ice.USR_INSTALL, path.Base(u.Path)); nfs.ExistsFile(m, pp) { + } else if pp := path.Join(ice.USR_INSTALL, path.Base(u.Path)); nfs.Exists(m, pp) { return path.Join(ice.USR_INSTALL, strings.Split(m.Cmd(nfs.TAR, pp, "", "1").Append(nfs.FILE), ice.PS)[0]) } else { return p @@ -31,7 +31,7 @@ func _install_download(m *ice.Message) { link := m.Option(web.LINK) name := path.Base(kit.ParseURL(link).Path) file := path.Join(kit.Select(ice.USR_INSTALL, m.Option(nfs.PATH)), name) - if nfs.ExistsFile(m, file) { + if nfs.Exists(m, file) { m.Cmdy(nfs.DIR, file) return } @@ -78,14 +78,14 @@ func _install_order(m *ice.Message, arg ...string) { p := _install_path(m, "") if m.Option(nfs.PATH) == "" { kit.For([]string{"", "sbin", "bin", "_install/bin"}, func(v string) { - kit.If(nfs.ExistsFile(m, path.Join(p, v)), func() { m.Option(nfs.PATH, v) }) + kit.If(nfs.Exists(m, path.Join(p, v)), func() { m.Option(nfs.PATH, v) }) }) } m.Cmdy(cli.SYSTEM, nfs.PUSH, path.Join(p, m.Option(nfs.PATH))) } func _install_spawn(m *ice.Message, arg ...string) { if kit.Int(m.Option(tcp.PORT)) >= 10000 { - if p := path.Join(ice.USR_LOCAL_DAEMON, m.Option(tcp.PORT)); nfs.ExistsFile(m, p) { + if p := path.Join(ice.USR_LOCAL_DAEMON, m.Option(tcp.PORT)); nfs.Exists(m, p) { m.Echo(p) return } @@ -95,7 +95,7 @@ func _install_spawn(m *ice.Message, arg ...string) { target, source := path.Join(ice.USR_LOCAL_DAEMON, m.Option(tcp.PORT)), _install_path(m, "") nfs.MkdirAll(m, target) defer m.Echo(target) - if m.Option(INSTALL) == "" && nfs.ExistsFile(m, kit.Path(source, _INSTALL)) { + if m.Option(INSTALL) == "" && nfs.Exists(m, kit.Path(source, _INSTALL)) { m.Option(INSTALL, _INSTALL) } nfs.DirDeepAll(m.Spawn(), path.Join(source, m.Option(INSTALL)), "", func(value ice.Maps) { @@ -177,7 +177,7 @@ func init() { nfs.TRASH: {Hand: func(m *ice.Message, arg ...string) { _install_trash(m, arg...) }}, nfs.PATH: {Hand: func(m *ice.Message, arg ...string) { m.Echo(_install_path(m, kit.Select("", arg, 0))) }}, nfs.SOURCE: {Name: "source link* path", Hand: func(m *ice.Message, arg ...string) { - if m.Option(nfs.DIR_ROOT, path.Join(_install_path(m, ""), _INSTALL)); !nfs.ExistsFile(m, m.Option(nfs.DIR_ROOT)) { + if m.Option(nfs.DIR_ROOT, path.Join(_install_path(m, ""), _INSTALL)); !nfs.Exists(m, m.Option(nfs.DIR_ROOT)) { m.Option(nfs.DIR_ROOT, path.Join(_install_path(m, ""))) } m.Cmdy(nfs.DIR, m.Option(nfs.PATH)).StatusTimeCount(nfs.PATH, m.Option(nfs.DIR_ROOT)) diff --git a/core/code/webpack.go b/core/code/webpack.go index 04e2b9a0..47a069a7 100644 --- a/core/code/webpack.go +++ b/core/code/webpack.go @@ -124,7 +124,7 @@ func init() { mdb.HashCreate(m, m.OptionSimple(nfs.PATH)) }}, cli.BUILD: {Name: "build name*=hi", Hand: func(m *ice.Message, arg ...string) { - kit.If(!nfs.ExistsFile(m, USR_PUBLISH_CAN_JS), func() { m.Cmd("", mdb.CREATE) }) + kit.If(!nfs.Exists(m, USR_PUBLISH_CAN_JS), func() { m.Cmd("", mdb.CREATE) }) _webpack_build(m, _publish(m, m.Option(mdb.NAME))) }}, nfs.TRASH: {Hand: func(m *ice.Message, arg ...string) { diff --git a/core/wiki/field.go b/core/wiki/field.go index dbed773a..3b33925a 100644 --- a/core/wiki/field.go +++ b/core/wiki/field.go @@ -75,7 +75,7 @@ func _field_show(m *ice.Message, name, text string, arg ...string) { } kit.Value(meta, "msg", msg.FormatMeta(), kit.Keys(FEATURE, "mode"), "simple") case SPARK: - if arg[i+1][0] == '@' && nfs.ExistsFile(m, arg[i+1][1:]) { + if arg[i+1][0] == '@' && nfs.Exists(m, arg[i+1][1:]) { msg.Cmdy(nfs.CAT, arg[i+1][1:]) } else { msg.Echo(strings.TrimSpace(arg[i+1])) diff --git a/data.go b/data.go index f9ac9bb2..b10ac66f 100644 --- a/data.go +++ b/data.go @@ -1,7 +1,6 @@ package ice import ( - "bufio" "os" "path" "strings" @@ -55,9 +54,9 @@ func SaveImportant(m *Message, arg ...string) { func loadImportant(m *Message) { if f, e := os.Open(VAR_DATA_IMPORTANT); e == nil { defer f.Close() - for bio := bufio.NewScanner(f); bio.Scan(); { - kit.If(bio.Text() != "" && !strings.HasPrefix(bio.Text(), "# "), func() { m.Cmd(kit.Split(bio.Text())) }) - } + kit.For(f, func(s string) { + kit.If(s != "" && !strings.HasPrefix(s, "# "), func() { m.Cmd(kit.Split(s)) }) + }) } Info.Important = true } diff --git a/misc/bash/favor.go b/misc/bash/favor.go index fe2e43a9..3cce64c1 100644 --- a/misc/bash/favor.go +++ b/misc/bash/favor.go @@ -18,7 +18,7 @@ func init() { mdb.INSERT: {Name: "insert zone*=demo type=shell name=1 text=pwd pwd=/home"}, cli.SYSTEM: {Hand: func(m *ice.Message, arg ...string) { if len(arg) > 0 && arg[0] == ice.RUN { - if msg := mdb.ZoneSelect(m.Spawn(), m.Option(mdb.ZONE), m.Option(mdb.ID)); nfs.ExistsFile(m, msg.Append(cli.PWD)) { + if msg := mdb.ZoneSelect(m.Spawn(), m.Option(mdb.ZONE), m.Option(mdb.ID)); nfs.Exists(m, msg.Append(cli.PWD)) { m.Option(cli.CMD_DIR, msg.Append(cli.PWD)) } ctx.ProcessField(m, "", nil, arg...) diff --git a/misc/bash/sync.go b/misc/bash/sync.go index 3c69dd25..ed9133e1 100644 --- a/misc/bash/sync.go +++ b/misc/bash/sync.go @@ -26,7 +26,7 @@ func init() { mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) { m.Cmdy(FAVOR, mdb.INPUTS, arg) }}, cli.SYSTEM: {Hand: func(m *ice.Message, arg ...string) { if len(arg) > 0 && arg[0] == ice.RUN { - if msg := mdb.ListSelect(m.Spawn(), m.Option(mdb.ID)); nfs.ExistsFile(m, msg.Append(cli.PWD)) { + if msg := mdb.ListSelect(m.Spawn(), m.Option(mdb.ID)); nfs.Exists(m, msg.Append(cli.PWD)) { m.Option(cli.CMD_DIR, msg.Append(cli.PWD)) } ctx.ProcessField(m, "", nil, arg...) diff --git a/misc/git/repos.go b/misc/git/repos.go index 88e03163..0673bc4b 100644 --- a/misc/git/repos.go +++ b/misc/git/repos.go @@ -206,13 +206,13 @@ func init() { if len(arg) < 4 { m.RenderStatusBadRequest() return - } else if path.Join(arg[:3]...) == ice.Info.Make.Module && nfs.ExistsFile(m, path.Join(arg[3:]...)) { + } else if path.Join(arg[:3]...) == ice.Info.Make.Module && nfs.Exists(m, path.Join(arg[3:]...)) { m.RenderDownload(path.Join(arg[3:]...)) return } p := path.Join(kit.Select(ice.USR_REQUIRE, m.Cmdx(cli.SYSTEM, "go", "env", "GOMODCACHE")), path.Join(arg...)) - if !nfs.ExistsFile(m, p) { - if p = path.Join(ice.USR_REQUIRE, path.Join(arg...)); !nfs.ExistsFile(m, p) { + if !nfs.Exists(m, p) { + if p = path.Join(ice.USR_REQUIRE, path.Join(arg...)); !nfs.Exists(m, p) { ls := strings.SplitN(path.Join(arg[:3]...), ice.AT, 2) if v := kit.Select(ice.Info.Gomod[ls[0]], ls, 1); v == "" { m.Cmd(cli.SYSTEM, "git", "clone", "https://"+ls[0], path.Join(ice.USR_REQUIRE, path.Join(arg[:3]...))) diff --git a/misc/git/server.go b/misc/git/server.go index 09548578..b6661cc7 100644 --- a/misc/git/server.go +++ b/misc/git/server.go @@ -125,12 +125,12 @@ func init() { if err := _server_login(m); m.Warn(err, ice.ErrNotLogin) { web.RenderHeader(m.W, "WWW-Authenticate", `Basic realm="git server"`) return - } else if !nfs.ExistsFile(m, repos) { + } else if !nfs.Exists(m, repos) { m.Logs(mdb.CREATE, REPOS, repos) _repos_init(m, repos) } case "upload-pack": - if m.Warn(!nfs.ExistsFile(m, repos), ice.ErrNotFound, arg[0]) { + if m.Warn(!nfs.Exists(m, repos), ice.ErrNotFound, arg[0]) { return } } diff --git a/misc/git/total.go b/misc/git/total.go index a09c0ad7..e6f38b10 100644 --- a/misc/git/total.go +++ b/misc/git/total.go @@ -68,7 +68,7 @@ func init() { }}, "_sum": {Name: "_sum [path] [total] [count|date] args...", Help: "统计量", Hand: func(m *ice.Message, arg ...string) { if len(arg) > 0 { - if nfs.ExistsFile(m, _git_dir(arg[0])) || nfs.ExistsFile(m, path.Join(arg[0], REFS_HEADS)) { + if nfs.Exists(m, _git_dir(arg[0])) || nfs.Exists(m, path.Join(arg[0], REFS_HEADS)) { m.Option(cli.CMD_DIR, arg[0]) arg = arg[1:] } diff --git a/misc/input/input.go b/misc/input/input.go index 51683729..4d8f1186 100644 --- a/misc/input/input.go +++ b/misc/input/input.go @@ -1,7 +1,6 @@ package input import ( - "bufio" "bytes" "encoding/csv" "fmt" @@ -50,16 +49,16 @@ func (s input) Load(m *ice.Message, arg ...string) { s.Zone.Remove(m, mdb.ZONE, lib) s.Zone.Create(m, kit.Simple(mdb.ZONE, lib, ctx.ConfigSimple(m.Message, mdb.LIMIT, mdb.LEAST, mdb.STORE, mdb.FSIZE))...) prefix := kit.Keys(mdb.HASH, m.Result()) - for bio := bufio.NewScanner(f); bio.Scan(); { - if strings.HasPrefix(bio.Text(), "# ") { - continue + kit.For(f, func(s string) { + if strings.HasPrefix(s, "# ") { + return } - line := kit.Split(bio.Text()) + line := kit.Split(s) if len(line) < 2 || (len(line) > 2 && line[2] == "0") { - continue + return } mdb.Grow(m.Message, m.PrefixKey(), prefix, kit.Dict(TEXT, line[0], CODE, line[1], WEIGHT, kit.Select("999999", line, 2))) - } + }) mdb.Conf(m, m.PrefixKey(), kit.Keys(prefix, kit.Keym(mdb.LIMIT)), 0) mdb.Conf(m, m.PrefixKey(), kit.Keys(prefix, kit.Keym(mdb.LEAST)), 0) m.Echo("%s: %d", lib, mdb.Grow(m.Message, m.PrefixKey(), prefix, kit.Dict(TEXT, "成功", CODE, "z", WEIGHT, "0"))) diff --git a/misc/node/npm.go b/misc/node/npm.go index 662c478f..2c8b0985 100644 --- a/misc/node/npm.go +++ b/misc/node/npm.go @@ -17,7 +17,7 @@ type npm struct { func (s npm) Require(m *ice.Message, arg ...string) { p := path.Join(ice.USR_MODULES, path.Join(arg...)) - kit.If(!nfs.ExistsFile(m, p), func() { m.Cmd(cli.SYSTEM, "npm", "install", arg[0], kit.Dict(cli.CMD_DIR, ice.USR)) }) + kit.If(!nfs.Exists(m, p), func() { m.Cmd(cli.SYSTEM, "npm", "install", arg[0], kit.Dict(cli.CMD_DIR, ice.USR)) }) m.RenderDownload(p) } func (s npm) List(m *ice.Message) { diff --git a/misc/qrcode/qrcode.go b/misc/qrcode/qrcode.go index 0c2e940f..aaee1fe6 100644 --- a/misc/qrcode/qrcode.go +++ b/misc/qrcode/qrcode.go @@ -4,9 +4,7 @@ import ( "shylinux.com/x/go-qrcode" ) -type QRCode struct { - *qrcode.QRCode -} +type QRCode struct{ *qrcode.QRCode } func New(text string) *QRCode { qr, _ := qrcode.New(text, qrcode.Medium) diff --git a/type.go b/type.go index 832d817d..0791c9b2 100644 --- a/type.go +++ b/type.go @@ -249,7 +249,9 @@ func (m *Message) Spawn(arg ...Any) *Message { for _, val := range arg { switch val := val.(type) { case []byte: - m.Warn(json.Unmarshal(val, &msg.meta)) + if m.Warn(json.Unmarshal(val, &msg.meta), string(val)) { + m.Debug(m.FormatStack(1, 100)) + } case Option: msg.Option(val.Name, val.Value) case Maps: