nfs

package
v1.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 8, 2019 License: MIT Imports: 22 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
	Caches: map[string]*ctx.Cache{
		"nfile": &ctx.Cache{Name: "nfile", Value: "0", Help: "已经打开的文件数量"},
	},
	Configs: map[string]*ctx.Config{
		"term": &ctx.Config{Name: "term", Value: map[string]interface{}{
			"use": "false",
			"mouse": map[string]interface{}{
				"resize": false,
			},
			"width": 80, "height": "24",

			"left": 0, "top": 0, "right": 80, "bottom": 24,
			"cursor_x": 0, "cursor_y": 0, "fgcolor": -1, "bgcolor": -1,
			"prompt": "", "wrap": "false",
			"scroll_count": "5",
			"scroll_lines": "5",
			"begin_row":    0, "begin_col": 0,

			"shadow":      "hello",
			"show_shadow": "false",

			"rest_fg": "0",
			"rest_bg": "7",
			"pick_fg": "0",
			"pick_bg": "7",
			"pick":    "",

			"help_index":     0,
			"help_state":     "command",
			"help_next_auto": "=",
			"help_stack":     []interface{}{},
			"help_table":     map[string]interface{}{},
		}, Help: "二维码的默认大小"},
		"auto": &ctx.Config{Name: "auto", Value: map[string]interface{}{
			"!": map[string]interface{}{
				"state":     "message",
				"next_auto": ":",
				"color":     2, "cmd": "message",
				"table": "message", "field": "code",
				"format": "%s(%s) %s->%s %s %s", "fields": []interface{}{"code", "time", "source", "target", "details", "options"},
			},
			"~": map[string]interface{}{
				"state": "context", "next_auto": ":",
				"color": 2, "cmd": "context",
				"table": "context", "field": "name",
				"format": "%s(%s) %s %s", "fields": []interface{}{"name", "status", "stream", "help"},
			},
			"": map[string]interface{}{
				"state": "command", "next_auto": "=",
				"color": 3, "cmd": "command",
				"table": "command", "field": "key",
				"format": "%s %s", "fields": []interface{}{"key", "name"},
			},
			":": map[string]interface{}{
				"state": "command", "next_auto": "=",
				"color": 3, "cmd": "command",
				"table": "command", "field": "key",
				"format": "%s %s", "fields": []interface{}{"key", "name"},
			},
			"=": map[string]interface{}{
				"cmd":    "help",
				"format": "%s %s %s ", "fields": []interface{}{"value", "name", "help"},
				"color": 3, "table": "command", "field": "value",
				"state": "argument", "next_auto": "=",
			},
			"@": map[string]interface{}{
				"state": "config", "next_auto": "@",
				"color": 4, "cmd": "config",
				"table": "config", "field": "key",
				"format": "%s(%s) %s", "fields": []interface{}{"key", "value", "name"},
			},
			"$": map[string]interface{}{
				"state": "cache", "next_auto": "$",
				"color": 7, "cmd": "cache",
				"table": "cache", "field": "key",
				"format": "%s(%s) %s", "fields": []interface{}{"key", "value", "name"},
			},
		}, Help: "读取文件的缓存区的大小"},

		"buf_size":   &ctx.Config{Name: "buf_size", Value: "81920", Help: "读取文件的缓存区的大小"},
		"dir_type":   &ctx.Config{Name: "dir_type(file/dir/both/all)", Value: "both", Help: "dir命令输出的文件类型, file: 只输出普通文件, dir: 只输出目录文件, 否则输出所有文件"},
		"dir_fields": &ctx.Config{Name: "dir_fields(time/type/name/size/line/hash)", Value: "time size line filename", Help: "dir命令输出文件名的类型, name: 文件名, tree: 带缩进的文件名, path: 相对路径, full: 绝对路径"},

		"grep": &ctx.Config{Name: "grep", Value: map[string]interface{}{
			"list": []interface{}{},
		}, Help: "dir命令输出文件名的类型, name: 文件名, tree: 带缩进的文件名, path: 相对路径, full: 绝对路径"},
		"git": &ctx.Config{Name: "git", Value: map[string]interface{}{
			"args":   []interface{}{"-C", "@git_dir"},
			"info":   map[string]interface{}{"cmds": []interface{}{"log", "status", "branch"}},
			"update": map[string]interface{}{"cmds": []interface{}{"stash", "pull", "pop"}},
			"pop":    map[string]interface{}{"args": []interface{}{"stash", "pop"}},
			"commit": map[string]interface{}{"args": []interface{}{"commit", "-am"}},
			"branch": map[string]interface{}{"args": []interface{}{"branch", "-v"}},
			"status": map[string]interface{}{"args": []interface{}{"status", "-sb"}},
			"log":    map[string]interface{}{"args": []interface{}{"log", "-n", "@page.limit", "--skip", "@page.offset", "pretty", "date"}},
			"trans": map[string]interface{}{
				"date":   "--date=format:%m/%d %H:%M",
				"pretty": "--pretty=format:%h %ad %an %s",
			},
		}, Help: "命令集合"},
		"paths": &ctx.Config{Name: "paths", Value: []interface{}{"var", "usr", "etc", "bin", ""}, Help: "文件路径"},
	},
	Commands: map[string]*ctx.Command{
		"_init": &ctx.Command{Name: "_init", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
			m.Conf("paths", -2, m.Conf("runtime", "boot.ctx_home"))
			m.Conf("paths", -2, m.Conf("runtime", "boot.ctx_root"))
			return
		}},
		"_exit": &ctx.Command{Name: "_init", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
			if m.Confs("term", "use") {
				termbox.Close()
			}
			return
		}},
		"pwd": &ctx.Command{Name: "pwd [all] | [[index] path] ", Help: "工作目录,all: 查看所有, index path: 设置路径, path: 设置当前路径", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
			if len(arg) > 0 && arg[0] == "all" {
				m.Cmdy("nfs.config", "paths")
				return
			}

			index := 0
			if len(arg) > 1 {
				index, arg = kit.Int(arg[0]), arg[1:]
			}
			for i, v := range arg {
				m.Log("info", "paths %s %s", index+i, v)
				m.Confv("paths", index+i, v)
			}

			if p := m.Conf("paths", index); path.IsAbs(p) {
				m.Echo("%s", p)
			} else if wd, e := os.Getwd(); m.Assert(e) {
				m.Echo("%s", path.Join(wd, p))
			}
			return
		}},
		"dir": &ctx.Command{Name: "dir [path [fields...]]", Help: []string{"查看目录, path: 路径, fields...: 查询字段, time|type|full|path|tree|filename|size|line|hash",
			"dir_deep: 递归查询", "dir_type both|file|dir|all: 文件类型", "dir_reg reg: 正则表达式", "dir_sort field order: 排序"},
			Form: map[string]int{"dir_deep": 0, "dir_type": 1, "dir_reg": 1, "dir_sort": 2},
			Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
				if len(arg) == 0 {
					arg = append(arg, "")
				}

				wd, e := os.Getwd()
				m.Assert(e)
				trip := len(wd) + 1

				rg, e := regexp.Compile(m.Option("dir_reg"))

				m.Confm("paths", func(index int, value string) bool {

					p := path.Join(value, arg[0])
					if s, e := os.Stat(p); e == nil {
						if s.IsDir() {
							dir(m, p, 0, kit.Right(m.Has("dir_deep")), m.Confx("dir_type"), trip, rg,
								strings.Split(m.Confx("dir_fields", strings.Join(arg[1:], " ")), " "),
								m.Conf("time_format"))
						} else {
							m.Append("directory", p)
						}
						return true
					}
					return false
				})

				if m.Has("dir_sort") {
					m.Sort(m.Meta["dir_sort"][0], m.Meta["dir_sort"][1:]...)
				}

				if len(m.Meta["append"]) == 1 {
					for _, v := range m.Meta[m.Meta["append"][0]] {
						m.Echo(v).Echo(" ")
					}
				} else {
					m.Table()
				}
				return
			}},
		"git": &ctx.Command{Name: "git sum", Help: "版本控制", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
			if len(arg) > 0 && arg[0] == "sum" {
				if out, e := exec.Command("git", "log", "--shortstat", "--pretty=commit: %ad", "--date=format:%Y-%m-%d").CombinedOutput(); m.Assert(e) {
					for _, v := range strings.Split(string(out), "commit: ") {
						if l := strings.Split(v, "\n"); len(l) > 2 {
							fs := strings.Split(strings.TrimSpace(l[2]), ", ")
							m.Add("append", "date", l[0])

							if adds := strings.Split(fs[1], " "); len(fs) > 2 {
								dels := strings.Split(fs[2], " ")
								m.Add("append", "adds", adds[0])
								m.Add("append", "dels", dels[0])
							} else if adds[1] == "insertions(+)" {
								m.Add("append", "adds", adds[0])
								m.Add("append", "dels", "0")
							} else {
								m.Add("append", "adds", "0")
								m.Add("append", "dels", adds[0])
							}
						}
					}
					m.Table()
				}
				return
			}

			if len(arg) == 0 {
				m.Cmdy("nfs.config", "git")
				return
			}

			if p := m.Cmdx("nfs.path", arg[0]); p != "" && !m.Confs("git", arg[0]) {
				m.Option("git_dir", p)
				arg = arg[1:]
			} else {
				wd, e := os.Getwd()
				m.Assert(e)
				m.Option("git_dir", wd)
			}

			cmds := []string{}
			if v := m.Confv("git", []string{arg[0], "cmds"}); v != nil {
				cmds = append(cmds, kit.Trans(v)...)
			} else {
				cmds = append(cmds, arg[0])
			}

			for _, cmd := range cmds {
				args := append([]string{}, kit.Trans(m.Confv("git", "args"))...)
				if v := m.Confv("git", []string{cmd, "args"}); v != nil {
					args = append(args, kit.Trans(v)...)
				} else {
					args = append(args, cmd)
				}
				args = append(args, arg[1:]...)

				for i, _ := range args {
					v := m.Parse(args[i])
					if v == args[i] || v == "" {
						args[i] = kit.Select(args[i], m.Conf("git", []string{"trans", args[i]}))
					} else {
						args[i] = v
					}
				}

				m.Cmd("cli.system", "git", args).Echo("\n\n").CopyTo(m)
			}
			return
		}},
		"grep": &ctx.Command{Name: "grep", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
			if len(arg) > 0 {
				switch arg[0] {
				case "add":
					m.Confv("grep", "list.-2", map[string]interface{}{
						"pos": 0, "offset": 0, "file": arg[1],
					})
					return

				case "head":
					m.Confm("grep", "list", func(index int, value map[string]interface{}) {
						if len(arg) == 1 {
							value["offset"] = 0
							value["pos"] = 0
						}
					})
					return
				case "tail":
					m.Confm("grep", "list", func(index int, value map[string]interface{}) {
						if len(arg) == 1 {
							value["pos"] = -1
							value["offset"] = 0
						}
					})
					return
				}
			}

			m.Confm("grep", "list", func(index int, value map[string]interface{}) {
				f, e := os.Open(kit.Format(value["file"]))
				if e != nil {
					m.Log("warn", "%v", e)
					return
				}
				defer f.Close()

				begin, e := f.Seek(int64(kit.Int(value["pos"])), 0)
				if kit.Int(value["pos"]) == -1 {
					begin, e = f.Seek(0, 2)
				}
				m.Assert(e)

				n := 0
				bio := bufio.NewScanner(f)
				for i := 0; i < m.Optioni("page.limit") && bio.Scan(); i++ {
					text := bio.Text()
					if len(arg) == 0 || strings.Contains(text, arg[0]) {
						m.Add("append", "index", index)
						m.Add("append", "file", path.Base(kit.Format(value["file"])))

						m.Add("append", "line", kit.Int(value["offset"]))
						m.Add("append", "text", text)
					} else {
						i--
					}
					n += len(text) + 1
					value["offset"] = kit.Int(value["offset"]) + 1
				}

				value["pos"] = begin + int64(n)
			})
			m.Table()
			return
		}},

		"draw": &ctx.Command{Name: "draw", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
			if len(arg) == 0 {
				m.Cmdy("nfs.dir", "src", "filename", "line", "size", "dir_deep", "dir_type", "file", "dir_sort", "line", "int_r")
				return
			}

			m.Append("text", m.Time())
			m.Append("style", map[int]string{
				0: "black",
				1: "red",
				2: "green",
				3: "yellow",
				4: "blue",
				5: "purple",
				6: "cyan",
				7: "white",
			}[rand.Intn(8)])
			switch arg[2] {
			case "drawText":
				x, y := rand.Intn(400), rand.Intn(300)
				m.Append("ps", kit.Format([]interface{}{
					map[string]int{"x": x, "y": y},
					map[string]int{"x": x + 200, "y": y},
				}))
			case "drawRect":
				x, y, l := rand.Intn(400), rand.Intn(300), rand.Intn(100)
				m.Append("ps", kit.Format([]interface{}{
					map[string]int{"x": x, "y": y},
					map[string]int{"x": x + l + l, "y": y + l},
				}))
			case "drawCircle":
				x, y, l := rand.Intn(400), rand.Intn(300), rand.Intn(100)
				m.Append("ps", kit.Format([]interface{}{
					map[string]int{"x": x, "y": y},
					map[string]int{"x": x + l, "y": y},
				}))
			}
			return
		}},

		"hash": &ctx.Command{Name: "hash filename", Help: "查找文件路径", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
			dir, name := path.Split(arg[0])
			m.Append("dir", dir)
			m.Append("name", name)
			m.Append("type", strings.TrimPrefix(path.Ext(arg[0]), "."))
			if s, e := os.Stat(arg[0]); e == nil && !s.IsDir() {
				m.Append("size", s.Size())
				if f, e := os.Open(arg[0]); e == nil {
					defer f.Close()
					md := md5.New()
					io.Copy(md, f)
					h := md.Sum(nil)
					m.Echo(hex.EncodeToString(h[:]))
				}
			}
			return
		}},
		"path": &ctx.Command{Name: "path filename", Help: "查找文件路径", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
			if len(arg) == 0 {
				return
			}

			m.Confm("paths", func(index int, value string) bool {
				p := path.Join(value, arg[0])
				if _, e := os.Stat(p); e == nil {
					m.Echo(p)
					return true
				}
				return false
			})
			return
		}},
		"copy": &ctx.Command{Name: "copy to from", Help: "查找文件路径", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
			dir, _ := path.Split(arg[0])
			m.Assert(os.MkdirAll(dir, 0777))

			to, e := os.Create(arg[0])
			m.Assert(e)
			defer to.Close()

			for _, from := range arg[1:] {
				f, e := os.Open(from)
				if e != nil {
					continue
				}
				defer f.Close()

				n, e := io.Copy(to, f)
				m.Assert(e)
				m.Log("info", "copy %d from %s to %s", n, from, arg[0])
			}
			m.Echo(arg[0])
			return
		}},
		"temp": &ctx.Command{Name: "temp data", Help: "查找文件路径", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
			h, _ := kit.Hash("uniq")
			name := fmt.Sprintf("var/tmp/file/%s", h)

			m.Assert(os.MkdirAll("var/tmp/file/", 0777))
			f, e := os.Create(name)
			m.Assert(e)
			defer f.Close()
			f.Write([]byte(arg[0]))

			m.Echo(name)
			return
		}},
		"trash": &ctx.Command{Name: "trash file", Help: "查找文件路径", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
			os.Remove(arg[0])
			return
		}},

		"load": &ctx.Command{Name: "load file [buf_size [pos]]", Help: "加载文件, buf_size: 加载大小, pos: 加载位置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
			if p, f, e := open(m, arg[0]); e == nil {
				defer f.Close()

				pos := kit.Int(kit.Select("0", arg, 2))
				size := kit.Int(m.Confx("buf_size", arg, 1))
				if size == -1 {
					s, e := f.Stat()
					m.Assert(e)
					size = int(s.Size())
				}
				buf := make([]byte, size)

				if l, e := f.ReadAt(buf, int64(pos)); e == io.EOF || m.Assert(e) {
					m.Log("info", "load %s %d %d", p, l, pos)
					m.Echo(string(buf[:l]))
				}
			}
			return
		}},
		"save": &ctx.Command{Name: "save file string...", Help: "保存文件, file: 保存的文件, string: 保存的内容", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
			if len(arg) == 1 && m.Has("data") {
				arg = append(arg, m.Option("data"))
			}

			dir := path.Dir(arg[0])
			if _, e = os.Stat(dir); e != nil {
				m.Assert(os.MkdirAll(dir, 0777))
			}

			if f, e := os.Create(arg[0]); m.Assert(e) {
				defer f.Close()
				for _, v := range arg[1:] {
					n, e := fmt.Fprint(f, v)
					m.Assert(e)
					m.Log("info", "save %s %d", arg[0], n)
				}
				m.Append("directory", arg[0])
				m.Echo(arg[0])
			}
			return
		}},
		"import": &ctx.Command{Name: "import filename [index]", Help: "导入数据", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
			p, f, e := open(m, arg[0])
			m.Assert(e)
			defer f.Close()

			s, e := f.Stat()
			m.Option("filepath", p)
			m.Option("filename", s.Name())
			m.Option("filesize", s.Size())
			m.Option("filetime", s.ModTime().Format(m.Conf("time_format")))

			switch {
			case strings.HasSuffix(arg[0], ".json"):
				var data interface{}
				de := json.NewDecoder(f)
				de.Decode(&data)

				m.Put("option", "filedata", data).Cmdy("ctx.trans", "filedata", arg[1:]).CopyTo(m)
			case strings.HasSuffix(arg[0], ".csv"):
				r := csv.NewReader(f)

				l, e := r.Read()
				m.Assert(e)
				m.Meta["append"] = l

				for l, e = r.Read(); e != nil; l, e = r.Read() {
					for i, v := range l {
						m.Add("append", m.Meta["append"][i], v)
					}
				}
				m.Table()
			default:
				b, e := ioutil.ReadAll(f)
				m.Assert(e)
				m.Echo(string(b))
			}
			return
		}},
		"export": &ctx.Command{Name: "export filename", Help: "导出数据", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
			tp := false
			if len(arg) > 0 && arg[0] == "time" {
				tp, arg = true, arg[1:]
			}

			p, f, e := open(m, kit.Select(arg[0], m.Format(arg[0]), tp), os.O_WRONLY|os.O_CREATE|os.O_TRUNC)
			m.Assert(e)
			defer f.Close()

			data := m.Optionv(kit.Select("data", arg, 1))
			if len(arg) > 0 && arg[0] == "all" {
				data, arg = m.Meta, arg[1:]
			}

			switch {
			case strings.HasSuffix(arg[0], ".json"):
				if data == nil && len(m.Meta["append"]) > 0 {
					lines := []interface{}{}
					nrow := len(m.Meta[m.Meta["append"][0]])
					for i := 0; i < nrow; i++ {
						line := map[string]interface{}{}
						for _, k := range m.Meta["append"] {
							line[k] = m.Meta[k][i]
						}

						lines = append(lines, line)
						data = lines
					}
				}

				en := json.NewEncoder(f)
				en.SetIndent("", "  ")
				en.Encode(data)
			case strings.HasSuffix(arg[0], ".csv"):
				fields := m.Meta["append"]
				if m.Options("fields") {
					fields = m.Meta["fields"]
				}

				if data == nil && len(m.Meta["append"]) > 0 {
					lines := []interface{}{}
					nrow := len(m.Meta[m.Meta["append"][0]])
					for i := 0; i < nrow; i++ {
						line := []string{}
						for _, k := range fields {
							line = append(line, m.Meta[k][i])
						}
						lines = append(lines, line)
						data = lines
					}
				}

				if data, ok := data.([]interface{}); ok {
					w := csv.NewWriter(f)
					w.Write(fields)
					for _, v := range data {
						w.Write(kit.Trans(v))
					}
					w.Flush()
				}
			case strings.HasSuffix(arg[0], ".png"):
				if data == nil {
					data = kit.Format(arg[1:])
				}

				qr, e := qrcode.New(kit.Format(data), qrcode.Medium)
				m.Assert(e)
				m.Assert(qr.Write(256, f))
			default:
				f.WriteString(kit.Format(m.Meta["result"]))
			}

			m.Set("append").Add("append", "directory", p)
			m.Set("result").Echo(p)
			return
		}},
		"json": &ctx.Command{Name: "json str", Help: "导入数据", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
			var data interface{}
			m.Assert(json.Unmarshal([]byte(arg[0]), &data))
			b, e := json.MarshalIndent(data, "", "  ")
			m.Assert(e)
			m.Echo(string(b))
			return
		}},

		"open": &ctx.Command{Name: "open file", Help: "打开文件, file: 文件名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
			if m.Has("io") {
			} else if p, f, e := open(m, arg[0], os.O_RDWR|os.O_CREATE); e == nil {
				m.Put("option", "in", f).Put("option", "out", f)
				arg[0] = p
			} else {
				return nil
			}

			m.Start(fmt.Sprintf("file%d", m.Capi("nfile")), fmt.Sprintf("file %s", arg[0]), "open", arg[0])
			m.Append("ps_target1", m.Cap("module"))
			m.Echo(m.Cap("module"))
			return
		}},
		"read": &ctx.Command{Name: "read [buf_size [pos]]", Help: "读取文件, buf_size: 读取大小, pos: 读取位置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
			if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) && nfs.in != nil {
				if len(arg) > 1 {
					m.Cap("pos", arg[1])
				}

				buf := make([]byte, kit.Int(m.Confx("buf_size", arg, 0)))
				if n, e := nfs.in.ReadAt(buf, int64(m.Capi("pos"))); e == io.EOF || m.Assert(e) {
					m.Capi("nread", n)
					if m.Capi("pos", n); n == 0 {
						m.Cap("pos", "0")
					}
				}
				m.Echo(string(buf))
			}
			return
		}},
		"write": &ctx.Command{Name: "write string [pos]", Help: "写入文件, string: 写入内容, pos: 写入位置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
			if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) && nfs.out != nil {
				if len(arg) > 1 {
					m.Cap("pos", arg[1])
				}

				if len(arg[0]) == 0 {
					m.Assert(nfs.out.Truncate(int64(m.Capi("pos"))))
					m.Cap("size", m.Cap("pos"))
					m.Cap("pos", "0")
				} else {
					n, e := nfs.out.WriteAt([]byte(arg[0]), int64(m.Capi("pos")))
					if m.Capi("nwrite", n); m.Assert(e) && m.Capi("pos", n) > m.Capi("size") {
						m.Cap("size", m.Cap("pos"))
					}
					nfs.out.Sync()
				}

				m.Echo(m.Cap("pos"))
			}
			return
		}},

		"scan": &ctx.Command{Name: "scan file name", Help: "扫描文件, file: 文件名, name: 模块名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
			if _, ok := m.Target().Server.(*NFS); m.Assert(ok) {
				if help := fmt.Sprintf("scan %s", arg[0]); arg[0] == "stdio" {
					m.Put("option", "in", os.Stdin).Put("option", "out", os.Stdout).Start(arg[0], help, key, arg[0])
				} else if p, f, e := open(m, arg[0]); m.Assert(e) {
					m.Put("option", "in", f).Start(fmt.Sprintf("file%d", m.Capi("nfile", 1)), help, key, p)
				}
			}
			return
		}},
		"printf": &ctx.Command{Name: "printf arg", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
			if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) {
				nfs.printf(arg)
			}
			return
		}},
		"prompt": &ctx.Command{Name: "prompt arg", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
			if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) {
				nfs.prompt(arg)
			}
			return
		}},
		"term": &ctx.Command{Name: "term action args...", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
			if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) {
				nfs.Term(m, arg[0], arg[1:])
			}
			return
		}},
		"action": &ctx.Command{Name: "action cmd", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
			if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) {
				msg := m.Cmd("cli.source", arg)
				nfs.printf(msg.Conf("prompt"), arg, "\n")
				nfs.printf(msg.Meta["result"])
			}
			return
		}},

		"remote": &ctx.Command{Name: "remote listen|dial args...", Help: "启动文件服务, args: 参考tcp模块, listen命令的参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
			if _, ok := m.Target().Server.(*NFS); m.Assert(ok) {
				m.Sess("tcp").Call(func(sub *ctx.Message) *ctx.Message {
					if sub.Has("node.port") {
						return sub
					}
					sub.Sess("ms_source", sub)
					sub.Sess("ms_target", m.Source())
					sub.Start(fmt.Sprintf("file%d", m.Capi("nfile", 1)), "远程文件")
					return sub
				}, arg)
			}
			return
		}},
		"send": &ctx.Command{Name: "send [file] args...", Help: "连接文件服务, args: 参考tcp模块, dial命令的参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
			if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) && nfs.io != nil {
				nfs.send <- m.Set("detail", arg)
			}
			return
		}},
	},
}

Functions

This section is empty.

Types

type NFS

type NFS struct {
	*ctx.Context
	// contains filtered or unexported fields
}

func (*NFS) Auto added in v1.1.1

func (nfs *NFS) Auto(what []rune, trigger string, index int) (change bool, frame map[string]interface{}, table []map[string]string, nindex int)

func (*NFS) Begin

func (nfs *NFS) Begin(m *ctx.Message, arg ...string) ctx.Server

func (*NFS) Close

func (nfs *NFS) Close(m *ctx.Message, arg ...string) bool

func (*NFS) Read

func (nfs *NFS) Read(p []byte) (n int, err error)

func (*NFS) Recv added in v1.1.1

func (nfs *NFS) Recv(line string) (field string, value string)

func (*NFS) Send added in v1.1.1

func (nfs *NFS) Send(meta string, arg ...interface{}) *NFS

func (*NFS) Show added in v1.1.1

func (nfs *NFS) Show(arg ...interface{}) bool

func (*NFS) Spawn

func (nfs *NFS) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server

func (*NFS) Start

func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool

func (*NFS) Term added in v1.1.1

func (nfs *NFS) Term(msg *ctx.Message, action string, args ...interface{}) *NFS

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL