ctx

package
v2.0.0+incompatible Latest Latest
Warning

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

Go to latest
Published: Jul 30, 2019 License: MIT Imports: 14 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var CGI = template.FuncMap{
	"option": func(arg ...interface{}) interface{} {
		return index("option", arg...)
	},
	"options": func(arg ...interface{}) string {
		switch value := index("option", arg...).(type) {
		case string:
			return value
		case []string:
			return strings.Join(value, "")
		}
		return ""
	},
}
View Source
var Index = &Context{Name: "ctx", Help: "模块中心", Server: &CTX{},
	Caches: map[string]*Cache{
		"ngo":      &Cache{Name: "ngo", Value: "0", Help: "协程数量"},
		"nserver":  &Cache{Name: "nserver", Value: "0", Help: "服务数量"},
		"ncontext": &Cache{Name: "ncontext", Value: "0", Help: "模块数量"},
		"nmessage": &Cache{Name: "nmessage", Value: "1", Help: "消息数量"},
	},
	Configs: map[string]*Config{
		"time": &Config{Name: "timer", Value: map[string]interface{}{
			"unit": 1000, "close": "open", "format": "2006-01-02 15:04:05",
		}, Help: "时间参数"},
		"table": &Config{Name: "table", Value: map[string]interface{}{
			"space": " ", "compact": "false", "col_sep": " ", "row_sep": "\n",
			"offset": 0, "limit": 10,
		}, Help: "制表"},
		"call_timeout": &Config{Name: "call_timeout", Value: "10s", Help: "回调超时"},
	},
	Commands: map[string]*Command{
		"_init": &Command{Name: "_init", Help: "启动", Hand: func(m *Message, c *Context, key string, arg ...string) (e error) {
			for _, x := range []string{"lex", "cli", "yac", "nfs", "aaa", "ssh", "web"} {
				m.Cmd(x + "._init")
			}
			return
		}},
		"_exit": &Command{Name: "_exit", Help: "退出", Hand: func(m *Message, c *Context, key string, arg ...string) (e error) {
			for _, x := range []string{"nfs", "cli"} {
				m.Cmd(x + "._exit")
			}
			return
		}},

		"help": &Command{Name: "help topic", Help: "帮助", Hand: func(m *Message, c *Context, key string, arg ...string) (e error) {
			if len(arg) == 0 {
				m.Echo("usage: help context [module [command|config|cache name]]\n")
				m.Echo("     : 查看模块信息, module: 模块名, command: 模块命令, config: 模块配置, cache: 模块缓存, name: 模块参数\n")
				m.Echo("usage: help command [name]\n")
				m.Echo("     : 查看当前环境下命令, name: 命令名\n")
				m.Echo("usage: help config [name]\n")
				m.Echo("     : 查看当前环境下配置, name: 配置名\n")
				m.Echo("usage: help cache [name]\n")
				m.Echo("     : 查看当前环境下缓存, name: 缓存名\n")
				m.Echo("\n")

				m.Echo("^_^  Welcome to context world  ^_^\n")
				m.Echo("Version: 1.0 A New Language, A New Framework\n")
				m.Echo("More: https://github.com/shylinux/context\n")
				m.Echo("More: https://shylinux.com/\n")
				return
			}

			switch arg[0] {
			case "context":
				switch len(arg) {
				case 1:
					keys := []string{}
					values := map[string]*Context{}
					m.Target().root.Travel(m, func(m *Message, i int) bool {
						if _, ok := values[m.Cap("module")]; !ok {
							keys = append(keys, m.Cap("module"))
							values[m.Cap("module")] = m.Target()
						}
						return false
					})

					sort.Strings(keys)
					for _, k := range keys {
						m.Echo("%s: %s %s\n", k, values[k].Name, values[k].Help)
					}
					break
				case 2:
					if msg := m.Find(arg[1]); msg != nil {
						m.Echo("%s: %s %s\n", arg[1], msg.Target().Name, msg.Target().Help)
						m.Echo("commands:\n")
						for k, v := range msg.Target().Commands {
							m.Echo("  %s: %s\n", k, v.Name)
						}
						m.Echo("configs:\n")
						for k, v := range msg.Target().Configs {
							m.Echo("  %s: %s\n", k, v.Name)
						}
						m.Echo("caches:\n")
						for k, v := range msg.Target().Caches {
							m.Echo("  %s: %s\n", k, v.Name)
						}
					}
				default:
					if msg := m.Find(arg[1]); msg != nil {
						m.Echo("%s: %s %s\n", arg[1], msg.Target().Name, msg.Target().Help)
						switch arg[2] {
						case "command":
							for k, v := range msg.Target().Commands {
								if k == arg[3] {
									m.Echo("%s: %s\n%s\n", k, v.Name, v.Help)
								}
							}
						case "config":
							for k, v := range msg.Target().Configs {
								if k == arg[3] {
									m.Echo("%s: %s\n  %s\n", k, v.Name, v.Help)
								}
							}
						case "cache":
							for k, v := range msg.Target().Caches {
								if k == arg[3] {
									m.Echo("%s: %s\n  %s\n", k, v.Name, v.Help)
								}
							}
						}
					}
				}
			case "command":
				keys := []string{}
				values := map[string]*Command{}
				for s := m.Target(); s != nil; s = s.context {
					for k, v := range s.Commands {
						if _, ok := values[k]; ok {
							continue
						}
						if len(arg) > 1 && k == arg[1] {
							switch help := v.Help.(type) {
							case []string:
								m.Echo("%s: %s\n", k, v.Name)
								for _, v := range help {
									m.Echo("  %s\n", v)
								}
							case string:
								m.Echo("%s: %s\n%s\n", k, v.Name, v.Help)
							}
							return
						}
						keys = append(keys, k)
						values[k] = v
					}
				}
				sort.Strings(keys)
				for _, k := range keys {
					m.Echo("%s: %s\n", k, values[k].Name)
				}
			case "config":
				keys := []string{}
				values := map[string]*Config{}
				for s := m.Target(); s != nil; s = s.context {
					for k, v := range s.Configs {
						if _, ok := values[k]; ok {
							continue
						}
						if len(arg) > 1 && k == arg[1] {
							m.Echo("%s(%s): %s %s\n", k, v.Value, v.Name, v.Help)
							return
						}
						keys = append(keys, k)
						values[k] = v
					}
				}
				sort.Strings(keys)
				for _, k := range keys {
					m.Echo("%s(%s): %s\n", k, values[k].Value, values[k].Name)
				}
			case "cache":
				keys := []string{}
				values := map[string]*Cache{}
				for s := m.Target(); s != nil; s = s.context {
					for k, v := range s.Caches {
						if _, ok := values[k]; ok {
							continue
						}
						if len(arg) > 1 && k == arg[1] {
							m.Echo("%s(%s): %s %s\n", k, v.Value, v.Name, v.Help)
							return
						}
						keys = append(keys, k)
						values[k] = v
					}
				}
				sort.Strings(keys)
				for _, k := range keys {
					m.Echo("%s(%s): %s\n", k, values[k].Value, values[k].Name)
				}
			}

			return
		}},
		"cache": &Command{Name: "cache [all] |key [value]|key = value|key name value help|delete key]", Help: "查看、读写、赋值、新建、删除缓存变量", Hand: func(m *Message, c *Context, key string, arg ...string) (e error) {
			all := false
			if len(arg) > 0 && arg[0] == "all" {
				arg, all = arg[1:], true
			}

			switch len(arg) {
			case 0:
				c.BackTrace(m, func(m *Message) bool {
					for k, v := range m.target.Caches {
						m.Add("append", "key", k)
						m.Add("append", "value", m.Cap(k))
						m.Add("append", "name", v.Name)
					}
					return !all
				})
				m.Sort("key", "str").Table()
				return
			case 1:
				m.Echo(m.Cap(arg[0]))
			case 2:
				if arg[0] == "delete" {
					delete(m.target.Caches, arg[1])
					return
				}
				m.Cap(arg[0], arg[1])
			case 3:
				m.Cap(arg[0], arg[0], arg[2], arg[0])
			default:
				m.Echo(m.Cap(arg[0], arg[1:]))
				return
			}
			return
		}},
		"config": &Command{Name: "config [all]", Help: []string{"配置管理",
			"brow: 配置列表",
			"key [chain [value]]: 读写配置",
			"export key...: 导出配置",
			"save|load file key...: 保存、加载配置",
			"create map|list|string key name help: 创建配置",
			"delete key: 删除配置",
		}, Form: map[string]int{"format": 1, "fields": -1}, Hand: func(m *Message, c *Context, key string, arg ...string) (e error) {
			all := false
			if len(arg) > 0 && arg[0] == "all" {
				arg, all = arg[1:], true
			}
			if len(arg) == 0 {
				arg = append(arg, "brow")
			}

			action, which := "", "-1"
			have := map[string]bool{}
			switch arg[0] {
			case "brow":
			case "export":
				action, arg = arg[0], arg[1:]
				for _, v := range arg {
					have[v] = true
				}
			case "save", "load":
				action, which, arg = arg[0], arg[1], arg[2:]
				for _, v := range arg {
					have[v] = true
				}
			case "create", "delete":
				action, arg = arg[0], arg[1:]

			default:
				var value interface{}
				if len(arg) > 2 && arg[2] == "map" {
					for i := 3; i < len(arg)-1; i += 2 {
						m.Confv(arg[0], []interface{}{arg[1], arg[i]}, arg[i+1])
					}
					value = m.Confv(arg[0], arg[1])
				} else if len(arg) > 2 && arg[2] == "list" {
					for i := 3; i < len(arg)-1; i += 1 {
						m.Confv(arg[0], []interface{}{arg[1], -2}, arg[i])
					}
					value = m.Confv(arg[0], arg[1])
				} else if len(arg) > 1 && arg[1] == "list" {
					for i := 2; i < len(arg)-1; i += 1 {
						m.Confv(arg[0], -2, arg[i])
					}
					value = m.Confv(arg[0])
				} else if len(arg) > 1 && arg[1] == "map" {
					for i := 2; i < len(arg)-1; i += 2 {
						m.Confv(arg[0], arg[i], arg[i+1])
					}
					value = m.Confv(arg[0])
				} else if len(arg) > 2 {
					value = m.Confv(arg[0], arg[1], arg[2])
				} else if len(arg) > 1 {
					value = m.Confv(arg[0], arg[1])
				} else {
					value = m.Confv(arg[0])
				}

				msg := m.Spawn().Put("option", "_cache", value).Cmd("trans", "_cache")
				m.Copy(msg, "append").Copy(msg, "result")
				return
			}

			save := map[string]interface{}{}
			if action == "load" {
				f, e := os.Open(m.Cmdx("nfs.path", which))
				if e != nil {
					return e
				}
				defer f.Close()

				de := json.NewDecoder(f)
				if e = de.Decode(&save); e != nil {
					m.Log("info", "e: %v", e)
				}
			}

			c.BackTrace(m, func(m *Message) bool {
				for k, v := range m.target.Configs {
					switch action {
					case "export", "save":
						if len(have) == 0 || have[k] {
							save[k] = v.Value
						}
					case "load":
						if x, ok := save[k]; ok && (len(have) == 0 || have[k]) {
							v.Value = x
						}
					case "create":
						m.Assert(k != arg[1], "%s exists", arg[1])
					case "delete":
						if k == arg[0] {
							m.Echo(kit.Formats(v.Value))
							delete(m.target.Configs, k)
						}
					default:
						m.Add("append", "key", k)
						m.Add("append", "value", strings.Replace(strings.Replace(m.Conf(k), "\n", "\\n", -1), "\t", "\\t", -1))
						m.Add("append", "name", v.Name)
					}
				}
				switch action {
				case "create":
					var value interface{}
					switch arg[0] {
					case "map":
						value = map[string]interface{}{}
					case "list":
						value = []interface{}{}
					default:
						value = ""
					}
					m.target.Configs[arg[1]] = &Config{Name: arg[2], Value: value, Help: arg[3]}
					m.Echo(arg[1])
					return true
				}
				return !all
			})
			m.Sort("key", "str").Table()

			switch action {
			case "save":
				buf, e := json.MarshalIndent(save, "", "  ")
				m.Assert(e)
				m.Sess("nfs").Add("option", "data", string(buf)).Cmd("save", which)
			case "export":
				buf, e := json.MarshalIndent(save, "", "  ")
				m.Assert(e)
				m.Echo("%s", string(buf))
			}
			return
		}},
		"command": &Command{Name: "command", Help: []string{"查看或操作命令",
			"brow [all|cmd]: 查看命令",
			"help cmd: 查看帮助",
			"cmd...: 执行命令",
			"list [begin [end]] [prefix] [test [key value]...]: 命令列表",
			"add [list_name name] [list_help help] [cmd|__|_|_val]...: 添加命令, __: 可选参数, _: 必选参数, _val: 默认参数",
		}, Hand: func(m *Message, c *Context, key string, arg ...string) (e error) {
			if len(arg) == 0 {
				arg = append(arg, "brow")
			}

			switch arg[0] {
			case "brow":
				c.BackTrace(m, func(m *Message) bool {
					for k, v := range m.target.Commands {
						if strings.HasPrefix(k, "_") {
							continue
						}
						if len(arg) == 1 || arg[1] == "all" {
							m.Add("append", "key", k)
							m.Add("append", "name", v.Name)
						} else if arg[1] == k {
							m.Add("append", "key", k)
							m.Add("append", "name", v.Name)
							m.Add("append", "help", v.Name)
						}
					}
					return len(arg) == 1 || arg[1] != "all"
				})
				m.Sort("key").Table()

			case "help":
				m.Cmdy("ctx.help", "command", arg[1:])

			case "list":
				arg = arg[1:]
				if m.Cap("list_count") == "" {
					break
				}
				begin, end := 0, m.Capi("list_count")
				if len(arg) > 0 {
					if n, e := strconv.Atoi(arg[0]); e == nil {
						begin, arg = n, arg[1:]
					}
				}
				if len(arg) > 0 {
					if n, e := strconv.Atoi(arg[0]); e == nil {
						end, arg = n, arg[1:]
					}
				}
				prefix := ""
				if len(arg) > 0 && arg[0] != "test" {
					prefix, arg = arg[0], arg[1:]
				}

				test := false
				if len(arg) > 0 && arg[0] == "test" {
					test, arg = true, arg[1:]
					for i := 0; i < len(arg)-1; i += 2 {
						m.Add("option", arg[i], arg[i+1])
					}
				}

				for i := begin; i < end; i++ {
					index := fmt.Sprintf("%d", i)
					if c, ok := m.target.Commands[index]; ok {
						if prefix != "" && !strings.HasPrefix(c.Help.(string), prefix) {
							continue
						}

						if test {
							msg := m.Spawn().Cmd(index)
							m.Add("append", "index", i)
							m.Add("append", "help", c.Help)
							m.Add("append", "msg", msg.messages[0].code)
							m.Add("append", "res", msg.Result(0))
						} else {
							m.Add("append", "index", i)
							m.Add("append", "help", c.Help)
							m.Add("append", "command", fmt.Sprintf("%s", strings.Replace(c.Name, "\n", "\\n", -1)))
						}
					}
				}
				m.Table()

			case "add":
				if m.target.Caches == nil {
					m.target.Caches = map[string]*Cache{}
				}
				if _, ok := m.target.Caches["list_count"]; !ok {
					m.target.Caches["list_count"] = &Cache{Name: "list_count", Value: "0", Help: "list_count"}
				}
				if m.target.Commands == nil {
					m.target.Commands = map[string]*Command{}
				}

				arg = arg[1:]
				list_name, list_help := "", "list_cmd"
				if len(arg) > 1 && arg[0] == "list_name" {
					list_name, arg = arg[1], arg[2:]
				}
				if len(arg) > 1 && arg[0] == "list_help" {
					list_help, arg = arg[1], arg[2:]
				}

				m.target.Commands[m.Cap("list_count")] = &Command{Name: strings.Join(arg, " "), Help: list_help, Hand: func(cmd *Message, c *Context, key string, args ...string) (e error) {
					list := []string{}
					for _, v := range arg {
						if v == "__" {
							if len(args) > 0 {
								v, args = args[0], args[1:]
							} else {
								continue
							}
						} else if strings.HasPrefix(v, "_") {
							if len(args) > 0 {
								v, args = args[0], args[1:]
							} else if len(v) > 1 {
								v = v[1:]
							} else {
								v = "''"
							}
						}
						list = append(list, v)
					}
					list = append(list, args...)

					msg := cmd.Sess("cli").Set("option", "current_ctx", m.target.Name).Cmd("source", strings.Join(list, " "))
					cmd.Copy(msg, "append").Copy(msg, "result").Copy(msg, "target")
					return
				}}

				if list_name != "" {
					m.target.Commands[list_name] = m.target.Commands[m.Cap("list_count")]
				}
				m.Capi("list_count", 1)

			default:
				m.Cmdy(arg)
			}
			return
		}},
		"context": &Command{Name: "context [find|search] [root|back|home] [first|last|rand|magic] [module] [cmd...|switch|list|spawn|start|close]",
			Help: []string{"查找并操作模块",
				"查找方法, find: 精确查找, search: 模糊搜索",
				"查找起点, root: 根模块, back: 父模块, home: 本模块",
				"过滤结果, first: 取第一个, last: 取最后一个, rand: 随机选择, magics: 智能选择",
				"操作方法, cmd...: 执行命令, switch: 切换为当前, list: 查看所有子模块, spwan: 创建子模块并初始化, start: 启动模块, close: 结束模块",
			}, Hand: func(m *Message, c *Context, key string, arg ...string) (e error) {
				action := "switch"
				if len(arg) == 0 {
					action = "list"
				}

				method := "search"
				if len(arg) > 0 {
					switch arg[0] {
					case "find", "search":
						method, arg = arg[0], arg[1:]
					}
				}

				root := true
				if len(arg) > 0 {
					switch arg[0] {
					case "root":
						root, arg = true, arg[1:]
					case "home":
						root, arg = false, arg[1:]
					case "back":
						root, arg = false, arg[1:]
						if m.target.context != nil {
							m.target = m.target.context
						}
					}
				}

				ms := []*Message{}
				if len(arg) > 0 {
					switch method {
					case "find":
						if msg := m.Find(arg[0], root); msg != nil {
							ms, arg = append(ms, msg), arg[1:]
						}
					case "search":
						msg := m.Search(arg[0], root)
						if len(msg) > 1 || msg[0] != nil {
							if len(arg) > 1 {
								switch arg[1] {
								case "first":
									ms, arg = append(ms, msg[0]), arg[2:]
								case "last":
									ms, arg = append(ms, msg[len(msg)-1]), arg[2:]
								case "rand":
									ms, arg = append(ms, msg[rand.Intn(len(msg))]), arg[2:]
								case "magics":
									ms, arg = append(ms, msg...), arg[2:]
								default:
									ms, arg = append(ms, msg[0]), arg[1:]
								}
							} else {
								ms, arg = append(ms, msg[0]), arg[1:]
							}
						}

					}
				}

				if len(ms) == 0 {
					ms = append(ms, m)
				}

				if len(arg) > 0 {
					switch arg[0] {
					case "switch", "list", "spawn", "start", "close":
						action, arg = arg[0], arg[1:]
					default:
						action = "cmd"
					}
				}

				for _, msg := range ms {
					if msg == nil {
						continue
					}

					switch action {
					case "cmd":
						if len(arg) == 0 {
							arg = append(arg, "command")
						} else if arg[0] == "command" && len(arg) > 1 {
							arg = arg[1:]
						}
						if msg.Cmd(arg); !msg.Hand {
							msg = msg.Cmd("nfs.cmd", arg)
						}
						msg.CopyTo(m)

					case "switch":
						m.target = msg.target

					case "list":
						cs := []*Context{}
						if msg.target.Name != "ctx" {
							cs = append(cs, msg.target.context)
						}
						msg.target.Travel(msg, func(msg *Message, n int) bool {
							cs = append(cs, msg.target)
							return false
						})
						msg = m.Spawn()

						for _, v := range cs {
							if msg.target = v; v == nil {
								m.Add("append", "names", "")
								m.Add("append", "ctx", "")
								m.Add("append", "msg", "")
								m.Add("append", "status", "")
								m.Add("append", "stream", "")
								m.Add("append", "helps", "")
								continue
							}

							m.Add("append", "names", msg.target.Name)
							if msg.target.context != nil {
								m.Add("append", "ctx", msg.target.context.Name)
							} else {
								m.Add("append", "ctx", "")
							}
							if msg.target.message != nil {
								m.Add("append", "msg", msg.target.message.code)
							} else {
								m.Add("append", "msg", "")
							}
							m.Add("append", "status", msg.Cap("status"))
							m.Add("append", "stream", msg.Cap("stream"))
							m.Add("append", "helps", msg.target.Help)
						}
						m.Table()

					case "spawn":
						msg.target.Spawn(msg, arg[0], arg[1]).Begin(msg, arg[2:]...)
						m.Copy(msg, "append").Copy(msg, "result").Copy(msg, "target")

					case "start":
						msg.target.Start(msg, arg...)
						m.Copy(msg, "append").Copy(msg, "result").Copy(msg, "target")

					case "close":
						msg := m.Spawn()
						m.target = msg.target.context
						msg.target.Close(msg.target.message, arg...)
					}
				}
				return
			}},

		"message": &Command{Name: "message [code] [cmd...]", Help: "查看消息", Hand: func(m *Message, c *Context, key string, arg ...string) (e error) {
			msg := m
			if len(arg) > 0 {
				msg = msg.root
				if code, e := strconv.Atoi(arg[0]); e == nil {
					ms := []*Message{m}
					for i := 0; i < len(ms); i++ {
						if ms[i].Code() == code {
							msg = ms[i]
							arg = arg[1:]
							break
						}
						ms = append(ms, ms[i].messages...)
					}
				}
			}

			if len(arg) == 0 {

				return
			}

			switch arg[0] {
			case "time", "code", "ship", "full", "chain", "stack":
				m.Echo(msg.Format(arg[0]))
			case "spawn":
				sub := msg.Spawn()
				m.Echo("%d", sub.code)
			case "call":
			case "back":
				msg.Back(m)
			case "free":
				msg.Free()
			default:
				msg = msg.Spawn().Cmd(arg)
				m.Copy(msg, "append").Copy(msg, "result")
			}
			return
		}},
		"detail": &Command{Name: "detail [index] [value...]", Help: "查看或添加参数", Hand: func(m *Message, c *Context, key string, arg ...string) (e error) {
			msg := m.Optionv("bio.msg").(*Message)
			if len(arg) == 0 {
				for i, v := range msg.Meta["detail"] {
					m.Push("index", i)
					m.Push("value", v)
				}
				m.Table()
				return
			}

			index := 0
			if i, e := strconv.Atoi(arg[0]); e == nil {
				index, arg = i, arg[1:]
			}
			m.Echo("%s", msg.Detail(index, arg))
			return
		}},
		"copy": &Command{Name: "copy", Help: "查看或添加选项", Hand: func(m *Message, c *Context, key string, arg ...string) (e error) {
			msg := m.Optionv("bio.msg").(*Message)
			for i := len(arg) - 1; i >= 0; i-- {
				if arg[i] == "" {
					arg = arg[:i]
				} else {
					break
				}
			}
			msg.Cmdy(arg)
			return
		}},
		"table": &Command{Name: "table", Help: "查看或添加选项", Hand: func(m *Message, c *Context, key string, arg ...string) (e error) {
			msg := m.Optionv("bio.msg").(*Message)
			if len(msg.Meta["append"]) == 0 {
				msg.Meta["append"] = arg
			} else {
				for i, k := range msg.Meta["append"] {
					msg.Push(k, kit.Select("", arg, i))
				}
			}
			msg.Log("fuck", "waht %v", msg.Meta)
			return
		}},
		"option": &Command{Name: "option", Help: "查看或添加选项", Hand: func(m *Message, c *Context, key string, arg ...string) (e error) {
			msg := m.Optionv("bio.msg").(*Message)
			switch v := msg.Optionv(arg[0]).(type) {
			case []string:
				m.Echo(strings.Join(v, ""))
			default:
				m.Echo(kit.Format(v))
			}
			return
		}},
		"append": &Command{Name: "append", Help: "查看或添加附加值", Hand: func(m *Message, c *Context, key string, arg ...string) (e error) {
			msg := m.Optionv("bio.msg").(*Message)
			if len(arg) == 0 {
				m.Copy(msg, "append")
				m.Table()
				return
			}
			if len(arg) == 1 {
				for i, v := range msg.Meta[arg[0]] {
					m.Push("index", i)
					m.Push("value", v)
				}
				m.Table()
				return
			}
			msg.Push(arg[0], arg[1])
			return
		}},
		"result": &Command{Name: "result [index] [value...]", Help: "查看或添加返回值", Hand: func(m *Message, c *Context, key string, arg ...string) (e error) {
			msg := m.Optionv("bio.msg").(*Message)
			if len(arg) == 0 {
				for i, v := range msg.Meta["result"] {
					m.Push("index", i)
					m.Push("value", strings.Replace(v, "\n", "\\n", -1))
				}
				m.Table()
				return
			}

			index := -2
			if i, e := strconv.Atoi(arg[0]); e == nil {
				index, arg = i, arg[1:]
			}
			m.Echo("%s", msg.Result(index, arg))
			return
		}},

		"trans": &Command{Name: "trans option [type|data|json] limit 10 [index...]", Help: "数据转换",
			Form: map[string]int{"format": 1, "fields": -1},
			Hand: func(m *Message, c *Context, key string, arg ...string) (e error) {
				value, arg := m.Optionv(arg[0]), arg[1:]
				if v, ok := value.(string); ok {
					json.Unmarshal([]byte(v), &value)
				}

				view := "data"
				if len(arg) > 0 {
					switch arg[0] {
					case "type", "data", "json":
						view, arg = arg[0], arg[1:]
					}
				}

				limit := kit.Int(kit.Select(m.Conf("table", "limit"), m.Option("table.limit")))
				if len(arg) > 0 && arg[0] == "limit" {
					limit, arg = kit.Int(arg[1]), arg[2:]
				}

				chain := strings.Join(arg, ".")
				if chain != "" {
					value = kit.Chain(value, chain)
				}

				switch view {
				case "type":
					switch value := value.(type) {
					case map[string]interface{}:
						for k, v := range value {
							m.Add("append", "key", k)
							m.Add("append", "type", fmt.Sprintf("%T", v))
						}
						m.Sort("key", "str").Table()
					case []interface{}:
						for k, v := range value {
							m.Add("append", "key", k)
							m.Add("append", "type", fmt.Sprintf("%T", v))
						}
						m.Sort("key", "int").Table()
					case nil:
					default:
						m.Add("append", "key", chain)
						m.Add("append", "type", fmt.Sprintf("%T", value))
						m.Sort("key", "str").Table()
					}
					return
				case "data":
				case "json":
					b, e := json.MarshalIndent(value, "", " ")
					m.Assert(e)
					m.Echo(string(b))
					return nil
				}

				switch val := value.(type) {
				case map[string]interface{}:
					if m.Option("format") == "table" {
						fields := []string{}
						has := map[string]bool{}
						if m.Options("fields") {
							fields = m.Optionv("fields").([]string)
						} else {
							i := 0
							for _, v := range val {
								if i++; i > kit.Int(kit.Select(m.Conf("table", "limit"), m.Option("table.limit"))) {
									break
								}
								if line, ok := v.(map[string]interface{}); ok {
									for k, _ := range line {
										if h, ok := has[k]; ok && h {
											continue
										}
										has[k], fields = true, append(fields, k)
									}
								}
							}
							sort.Strings(fields)
						}

						i := 0
						for k, v := range val {
							if i++; i > kit.Int(kit.Select(m.Conf("table", "limit"), m.Option("table.limit"))) {
								break
							}
							if line, ok := v.(map[string]interface{}); ok {
								m.Add("append", "key", k)
								for _, field := range fields {
									m.Add("append", field, kit.Format(line[field]))
								}
							}
						}
						m.Table()
						break
					}

					for k, v := range val {
						if m.Option("format") == "object" {
							m.Add("append", k, v)
							continue
						}

						m.Add("append", "key", k)
						switch val := v.(type) {
						case nil:
							m.Add("append", "value", "")
						case string:
							m.Add("append", "value", val)
						case float64:
							m.Add("append", "value", fmt.Sprintf("%d", int(val)))
						default:
							b, _ := json.Marshal(val)
							m.Add("append", "value", fmt.Sprintf("%s", string(b)))
						}
					}
					if m.Option("format") != "object" {
						m.Sort("key", "str")
					}
					m.Table()
				case map[string]string:
					for k, v := range val {
						m.Add("append", "key", k)
						m.Add("append", "value", v)
					}
					m.Sort("key", "str").Table()
				case []interface{}:
					fields := map[string]int{}
					for i, v := range val {
						if i >= limit {
							break
						}
						switch val := v.(type) {
						case map[string]interface{}:
							for k, _ := range val {
								fields[k]++
							}
						}
					}

					if len(fields) > 0 {
						for i, v := range val {
							if i >= limit {
								break
							}
							switch val := v.(type) {
							case map[string]interface{}:
								for k, _ := range fields {
									switch value := val[k].(type) {
									case nil:
										m.Add("append", k, "")
									case string:
										m.Add("append", k, value)
									case float64:
										m.Add("append", k, fmt.Sprintf("%d", int(value)))
									default:
										b, _ := json.Marshal(value)
										m.Add("append", k, fmt.Sprintf("%v", string(b)))
									}
								}
							}
						}
					} else {
						for i, v := range val {
							switch val := v.(type) {
							case nil:
								m.Add("append", "index", i)
								m.Add("append", "value", "")
							case string:
								m.Add("append", "index", i)
								m.Add("append", "value", val)
							case float64:
								m.Add("append", "index", i)
								m.Add("append", "value", fmt.Sprintf("%v", int(val)))
							default:
								m.Add("append", "index", i)
								b, _ := json.Marshal(val)
								m.Add("append", "value", fmt.Sprintf("%v", string(b)))
							}
						}
					}
					m.Table()
				case []string:
					for i, v := range val {
						m.Add("append", "index", i)
						m.Add("append", "value", v)
					}
					m.Table()
				case string:
					m.Echo("%s", val)
				case float64:
					m.Echo("%d", int(val))
				case nil:
				default:
					b, _ := json.Marshal(val)
					m.Echo("%s", string(b))
				}
				return
			}},
		"select": &Command{Name: "select field...",
			Form: map[string]int{"reg": 2, "eq": 2, "expand": 2, "hide": -1, "fields": -1, "group": 1, "order": 2, "limit": 1, "offset": 1, "format": -1, "trans_map": -1, "vertical": 0},
			Help: "选取数据", Hand: func(m *Message, c *Context, key string, arg ...string) (e error) {
				msg := m.Set("result").Spawn()

				if len(m.Meta["append"]) == 0 {
					return
				}
				nrow := len(m.Meta[m.Meta["append"][0]])
				keys := []string{}
				for i := 0; i < nrow; i++ {
					for j := 0; j < len(m.Meta["expand"]); j += 2 {
						var value interface{}
						json.Unmarshal([]byte(m.Meta[m.Meta["expand"][j]][i]), &value)
						if m.Meta["expand"][j+1] != "" {
							value = kit.Chain(value, m.Meta["expand"][j+1])
						}

						switch val := value.(type) {
						case map[string]interface{}:
							for k, _ := range val {
								keys = append(keys, k)
							}
						default:
							keys = append(keys, m.Meta["expand"][j+1])
						}
					}
				}
				for i := 0; i < nrow; i++ {
					for _, k := range keys {
						m.Add("append", k, "")
					}
				}
				for i := 0; i < nrow; i++ {
					for j := 0; j < len(m.Meta["expand"]); j += 2 {
						var value interface{}
						json.Unmarshal([]byte(m.Meta[m.Meta["expand"][j]][i]), &value)
						if m.Meta["expand"][j+1] != "" {
							value = kit.Chain(value, m.Meta["expand"][j+1])
						}

						switch val := value.(type) {
						case map[string]interface{}:
							for k, v := range val {
								switch val := v.(type) {
								case string:
									m.Meta[k][i] = val
								case float64:
									m.Meta[k][i] = fmt.Sprintf("%d", int(val))
								default:
									b, _ := json.Marshal(val)
									m.Meta[k][i] = string(b)
								}
							}
						case string:
							m.Meta[m.Meta["expand"][j+1]][i] = val
						default:
							m.Meta[m.Meta["expand"][j+1]][i] = kit.Format(val)
						}
					}
				}

				hides := map[string]bool{}
				for _, k := range m.Meta["hide"] {
					hides[k] = true
				}
				if len(arg) == 0 {
					arg = append(arg, m.Meta["append"]...)
				}
				for i := 0; i < nrow; i++ {

					if m.Has("eq") {
						if m.Meta[m.Meta["eq"][0]][i] != m.Meta["eq"][1] {
							continue
						}
					}
					if m.Has("reg") {
						if b, e := regexp.MatchString(m.Meta["reg"][1], m.Meta[m.Meta["reg"][0]][i]); e != nil || !b {
							continue
						}
					}
					for _, k := range arg {
						if hides[k] {
							continue
						}
						msg.Add("append", k, kit.Select("", m.Meta[k], i))
					}
				}
				if len(msg.Meta["append"]) == 0 {
					return
				}
				if len(msg.Meta[msg.Meta["append"][0]]) == 0 {
					return
				}

				if m.Set("append"); m.Has("group") {
					group := m.Option("group")
					nrow := len(msg.Meta[msg.Meta["append"][0]])

					for i := 0; i < nrow; i++ {
						count := 1

						if group != "" && msg.Meta[group][i] == "" {
							msg.Add("append", "count", 0)
							continue
						}

						for j := i + 1; j < nrow; j++ {
							if group == "" || msg.Meta[group][i] == msg.Meta[group][j] {
								count++
								for _, k := range msg.Meta["append"] {
									if k == "count" {
										continue
									}
									if k == group {
										continue
									}
									m, e := strconv.Atoi(msg.Meta[k][i])
									if e != nil {
										continue
									}
									n, e := strconv.Atoi(msg.Meta[k][j])
									if e != nil {
										continue
									}
									msg.Meta[k][i] = fmt.Sprintf("%d", m+n)

								}

								if group != "" {
									msg.Meta[group][j] = ""
								}
							}
						}

						msg.Add("append", "count", count)
						for _, k := range msg.Meta["append"] {
							m.Add("append", k, msg.Meta[k][i])
						}
						if group == "" {
							break
						}
					}
				} else {
					m.Copy(msg, "append")
				}

				if m.Has("order") {
					m.Sort(m.Option("order"), kit.Select("str", m.Meta["order"], 1))
				}

				offset := kit.Int(kit.Select("0", m.Option("offset")))
				limit := kit.Int(kit.Select(m.Conf("table", "limit"), m.Option("table.limit")))

				nrow = len(m.Meta[m.Meta["append"][0]])
				if offset > nrow {
					offset = nrow
				}
				if limit+offset > nrow {
					limit = nrow - offset
				}
				for _, k := range m.Meta["append"] {
					m.Meta[k] = m.Meta[k][offset : offset+limit]
				}

				for i := 0; i < len(m.Meta["trans_map"]); i += 3 {
					trans := m.Meta["trans_map"][i:]
					for j := 0; j < len(m.Meta[trans[0]]); j++ {
						if m.Meta[trans[0]][j] == trans[1] {
							m.Meta[trans[0]][j] = trans[2]
						}
					}
				}

				for i := 0; i < len(m.Meta["format"])-1; i += 2 {
					format := m.Meta["format"]
					for j, v := range m.Meta[format[i]] {
						if v != "" {
							m.Meta[format[i]][j] = fmt.Sprintf(format[i+1], v)
						}
					}
				}

				if m.Has("vertical") {
					msg := m.Spawn()
					nrow := len(m.Meta[m.Meta["append"][0]])
					sort.Strings(m.Meta["append"])
					msg.Add("append", "field", "")
					msg.Add("append", "value", "")
					for i := 0; i < nrow; i++ {
						for _, k := range m.Meta["append"] {
							msg.Add("append", "field", k)
							msg.Add("append", "value", m.Meta[k][i])
						}
						msg.Add("append", "field", "")
						msg.Add("append", "value", "")
					}
					m.Set("append").Copy(msg, "append")
				}

				m.Set("result").Table()
				return
			}},
	},
}
View Source
var Pulse = &Message{code: 0, time: time.Now(), source: Index, target: Index, Meta: map[string][]string{}}

Functions

func Start

func Start(args ...string) bool

Types

type CTX added in v1.1.1

type CTX struct {
	*Context
}

func (*CTX) Begin added in v1.1.1

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

func (*CTX) Close added in v1.1.1

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

func (*CTX) Spawn added in v1.1.1

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

func (*CTX) Start added in v1.1.1

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

type Cache

type Cache struct {
	Value string
	Name  string
	Help  string
	Hand  func(m *Message, x *Cache, arg ...string) string
}

type Command

type Command struct {
	Form map[string]int
	Name string
	Help interface{}
	Auto func(m *Message, c *Context, key string, arg ...string) (ok bool)
	Hand func(m *Message, c *Context, key string, arg ...string) (e error)
}

type Config

type Config struct {
	Value interface{}
	Name  string
	Help  string
	Hand  func(m *Message, x *Config, arg ...string) string
}

type Context

type Context struct {
	Name string
	Help string

	Caches   map[string]*Cache
	Configs  map[string]*Config
	Commands map[string]*Command

	Server
	// contains filtered or unexported fields
}

func (*Context) BackTrace added in v1.1.1

func (c *Context) BackTrace(m *Message, hand func(m *Message) (stop bool)) *Context

func (*Context) Begin

func (c *Context) Begin(m *Message, arg ...string) *Context

func (*Context) Close

func (c *Context) Close(m *Message, arg ...string) bool

func (*Context) Context

func (c *Context) Context() *Context

func (*Context) Message

func (c *Context) Message() *Message

func (*Context) Plugin added in v1.1.1

func (c *Context) Plugin(s *Context, args []string) string

func (*Context) Register

func (c *Context) Register(s *Context, x Server, args ...interface{}) *Context

func (*Context) Spawn

func (c *Context) Spawn(m *Message, name string, help string) *Context

func (*Context) Start

func (c *Context) Start(m *Message, arg ...string) bool

func (*Context) Travel added in v1.1.1

func (c *Context) Travel(m *Message, hand func(m *Message, n int) (stop bool)) *Context

type DEBUG added in v1.1.1

type DEBUG interface {
	Wait(*Message, ...interface{}) interface{}
	Goon(interface{}, ...interface{})
}

type LOGGER added in v1.1.1

type LOGGER interface {
	Log(*Message, string, string, ...interface{})
}

type Message

type Message struct {
	Hand bool
	Meta map[string][]string
	Data map[string]interface{}

	Sessions map[string]*Message
	// contains filtered or unexported fields
}

func (*Message) Add

func (m *Message) Add(meta string, key string, value ...interface{}) *Message

func (*Message) Append

func (m *Message) Append(key string, arg ...interface{}) string

func (*Message) Appendi

func (m *Message) Appendi(key string, arg ...interface{}) int64

func (*Message) Appends

func (m *Message) Appends(key string, arg ...interface{}) bool

func (*Message) Assert

func (m *Message) Assert(e interface{}, msg ...string) bool

func (*Message) Back

func (m *Message) Back(ms ...*Message) *Message

func (*Message) Call

func (m *Message) Call(cb func(msg *Message) (sub *Message), arg ...interface{}) *Message

func (*Message) CallBack

func (m *Message) CallBack(sync bool, cb func(msg *Message) (sub *Message), arg ...interface{}) *Message

func (*Message) Cap

func (m *Message) Cap(key string, arg ...interface{}) string

func (*Message) Capi

func (m *Message) Capi(key string, arg ...interface{}) int

func (*Message) Caps

func (m *Message) Caps(key string, arg ...interface{}) bool

func (*Message) Cmd

func (m *Message) Cmd(args ...interface{}) *Message

func (*Message) Cmdp added in v1.1.1

func (m *Message) Cmdp(t time.Duration, head []string, prefix []string, suffix [][]string) *Message

func (*Message) Cmds added in v1.1.1

func (m *Message) Cmds(args ...interface{}) bool

func (*Message) Cmdx added in v1.1.1

func (m *Message) Cmdx(args ...interface{}) string

func (*Message) Cmdy added in v1.1.1

func (m *Message) Cmdy(args ...interface{}) *Message

func (*Message) Code

func (m *Message) Code() int

func (*Message) Conf

func (m *Message) Conf(key string, args ...interface{}) string

func (*Message) Confi

func (m *Message) Confi(key string, arg ...interface{}) int

func (*Message) Confm added in v1.1.1

func (m *Message) Confm(key string, args ...interface{}) map[string]interface{}

func (*Message) Confs

func (m *Message) Confs(key string, arg ...interface{}) bool

func (*Message) Confv

func (m *Message) Confv(key string, args ...interface{}) interface{}

func (*Message) Confx

func (m *Message) Confx(key string, args ...interface{}) string

func (*Message) Copy

func (m *Message) Copy(msg *Message, arg ...string) *Message

func (*Message) CopyFuck added in v1.1.1

func (m *Message) CopyFuck(msg *Message, arg ...string) *Message

func (*Message) CopyTo added in v1.1.1

func (m *Message) CopyTo(msg *Message, arg ...string) *Message

func (*Message) Detail

func (m *Message) Detail(arg ...interface{}) string

func (*Message) Echo

func (m *Message) Echo(str string, arg ...interface{}) *Message

func (*Message) Find

func (m *Message) Find(name string, root ...bool) *Message

func (*Message) Form

func (m *Message) Form(x *Command, arg []string) []string

func (*Message) Format

func (m *Message) Format(arg ...interface{}) string

func (*Message) Free added in v1.1.1

func (m *Message) Free(cbs ...func(msg *Message) (done bool)) *Message

func (*Message) Gdb added in v1.1.1

func (m *Message) Gdb(arg ...interface{}) interface{}

func (*Message) Get

func (m *Message) Get(key string, arg ...interface{}) string

func (*Message) GoLoop added in v1.1.1

func (m *Message) GoLoop(msg *Message, hand ...func(msg *Message)) *Message

func (*Message) Gos added in v1.1.1

func (m *Message) Gos(msg *Message, hand ...func(msg *Message)) *Message

func (*Message) Goshy

func (m *Message) Goshy(input []string, index int, stack *kit.Stack, cb func(*Message)) bool

func (*Message) Has

func (m *Message) Has(key ...string) bool

func (*Message) Insert

func (m *Message) Insert(meta string, index int, arg ...interface{}) string

func (*Message) Log

func (m *Message) Log(action string, str string, arg ...interface{}) *Message

func (*Message) Magic added in v1.1.1

func (m *Message) Magic(begin string, chain interface{}, args ...interface{}) interface{}

func (*Message) Match added in v1.1.1

func (m *Message) Match(key string, spawn bool, hand func(m *Message, s *Context, c *Context, key string) bool) *Message

func (*Message) Option

func (m *Message) Option(key string, arg ...interface{}) string

func (*Message) Optioni

func (m *Message) Optioni(key string, arg ...interface{}) int

func (*Message) Options

func (m *Message) Options(key string, arg ...interface{}) bool

func (*Message) Optionv

func (m *Message) Optionv(key string, arg ...interface{}) interface{}

func (*Message) Parse

func (m *Message) Parse(arg interface{}) string

func (*Message) Push added in v1.1.1

func (m *Message) Push(str string, arg ...interface{}) *Message

func (*Message) Put

func (m *Message) Put(meta string, key string, value interface{}) *Message

func (*Message) Result

func (m *Message) Result(arg ...interface{}) string

func (*Message) Search

func (m *Message) Search(key string, root ...bool) []*Message

func (*Message) Sess

func (m *Message) Sess(key string, arg ...interface{}) *Message

func (*Message) Set

func (m *Message) Set(meta string, arg ...interface{}) *Message

func (*Message) Show added in v1.1.1

func (m *Message) Show(str string, args ...interface{}) *Message

func (*Message) Sort

func (m *Message) Sort(key string, arg ...string) *Message

func (*Message) Source

func (m *Message) Source() *Context

func (*Message) Spawn

func (m *Message) Spawn(arg ...interface{}) *Message

func (*Message) Start

func (m *Message) Start(name string, help string, arg ...string) bool

func (*Message) Table

func (m *Message) Table(cbs ...interface{}) *Message

func (*Message) Target

func (m *Message) Target() *Context

func (*Message) Time

func (m *Message) Time(arg ...interface{}) string

func (*Message) ToHTML added in v1.1.1

func (m *Message) ToHTML(style string) string

func (*Message) TryCatch

func (m *Message) TryCatch(msg *Message, safe bool, hand ...func(msg *Message)) *Message

func (*Message) Wait

func (m *Message) Wait() bool

type Server

type Server interface {
	Spawn(m *Message, c *Context, arg ...string) Server
	Begin(m *Message, arg ...string) Server
	Start(m *Message, arg ...string) bool
	Close(m *Message, arg ...string) bool
}

Jump to

Keyboard shortcuts

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