From c3227219573b343ecaa1bd3363a07db414788361 Mon Sep 17 00:00:00 2001 From: shylinux Date: Sun, 31 May 2020 18:19:25 +0800 Subject: [PATCH] add inner.go --- base/web/cache.go | 241 ++++++++++++++++++---------------- base/web/share.go | 312 +++++++++++++++++++++++++------------------- base/web/story.go | 37 +++--- core/chat/action.go | 19 +++ core/wiki/inner.go | 132 +++++++++++++++---- core/wiki/qrcode.go | 47 +++++++ core/wiki/video | 2 + core/wiki/video.go | 50 +++++++ go.mod | 2 + go.sum | 8 ++ misc/md/md.go | 3 +- name.go | 17 +++ type.go | 22 +++- 13 files changed, 600 insertions(+), 292 deletions(-) create mode 100644 core/wiki/qrcode.go create mode 100644 core/wiki/video create mode 100644 core/wiki/video.go create mode 100644 name.go diff --git a/base/web/cache.go b/base/web/cache.go index 7ec84bc2..c08526d9 100644 --- a/base/web/cache.go +++ b/base/web/cache.go @@ -12,140 +12,161 @@ import ( "os" ) +var CACHE = ice.Name("cache", Index) + +func _cache_list(m *ice.Message) { + m.Grows(CACHE, nil, "", "", func(index int, value map[string]interface{}) { + m.Push("", value) + }) +} +func _cache_save(m *ice.Message, method, kind, name, text string, arg ...string) { + size := kit.Int(kit.Select(kit.Format(len(text)), arg, 1)) + if method == "add" && size > 512 { + // 创建文件 + file := kit.Hashs(text) + if o, p, e := kit.Create(path.Join(m.Conf(CACHE, "meta.path"), file[:2], file)); m.Assert(e) { + defer o.Close() + + // 导入数据 + if n, e := o.WriteString(text); m.Assert(e) { + m.Log(ice.LOG_IMPORT, "%s: %s", kit.FmtSize(int64(n)), p) + text, arg = p, kit.Simple(p, n) + } + } + } + + // 添加数据 + h := m.Rich(CACHE, nil, kit.Dict( + kit.MDB_TYPE, kind, kit.MDB_NAME, name, kit.MDB_TEXT, text, + kit.MDB_FILE, kit.Select("", arg, 0), kit.MDB_SIZE, size, + )) + m.Log(ice.LOG_CREATE, "cache: %s %s: %s", h, kind, name) + + // 添加记录 + m.Grow(CACHE, nil, kit.Dict( + kit.MDB_TYPE, kind, kit.MDB_NAME, name, kit.MDB_TEXT, text, + kit.MDB_SIZE, size, "data", h, + )) + + // 返回结果 + m.Push("time", m.Time()) + m.Push("type", kind) + m.Push("name", name) + m.Push("text", text) + m.Push("size", size) + m.Push("data", h) +} +func _cache_show(m *ice.Message, key, file string) { + if m.Richs(CACHE, nil, key, func(key string, value map[string]interface{}) { + if value["file"] == "" { + if f, _, e := kit.Create(file); m.Assert(e) { + defer f.Close() + f.WriteString(kit.Format(value["text"])) + } + } else { + os.MkdirAll(path.Dir(file), 0777) + os.Remove(file) + os.Link(kit.Format(value["file"]), file) + } + }) == nil { + m.Cmdy(ice.WEB_SPIDE, "dev", "cache", "/cache/"+key) + os.MkdirAll(path.Dir(file), 0777) + os.Remove(file) + os.Link(m.Append("file"), file) + } + m.Echo(file) +} + +func _cache_catch(m *ice.Message, arg ...string) []string { + if f, e := os.Open(arg[2]); m.Assert(e) { + defer f.Close() + + // 创建文件 + h := kit.Hashs(f) + if o, p, e := kit.Create(path.Join(m.Conf(CACHE, "meta.path"), h[:2], h)); m.Assert(e) { + defer o.Close() + f.Seek(0, os.SEEK_SET) + + // 导入数据 + if n, e := io.Copy(o, f); m.Assert(e) { + m.Log(ice.LOG_IMPORT, "%s: %s", kit.FmtSize(n), p) + arg = kit.Simple(arg[0], arg[1], arg[2], p, p, n) + } + } + } + return arg +} +func _cache_upload(m *ice.Message, arg ...string) []string { + if f, h, e := m.R.FormFile(kit.Select("upload", arg, 1)); e == nil { + defer f.Close() + + // 创建文件 + file := kit.Hashs(f) + if o, p, e := kit.Create(path.Join(m.Conf(CACHE, "meta.path"), file[:2], file)); m.Assert(e) { + defer o.Close() + f.Seek(0, os.SEEK_SET) + + // 导入数据 + if n, e := io.Copy(o, f); m.Assert(e) { + m.Log(ice.LOG_IMPORT, "%s: %s", kit.FmtSize(n), p) + arg = kit.Simple(arg[0], h.Header.Get("Content-Type"), h.Filename, p, p, n) + } + } + } + return arg +} +func _cache_download(m *ice.Message, r *http.Response, arg ...string) []string { + if buf, e := ioutil.ReadAll(r.Body); m.Assert(e) { + defer r.Body.Close() + + // 创建文件 + file := kit.Hashs(string(buf)) + if o, p, e := kit.Create(path.Join(m.Conf(CACHE, "meta.path"), file[:2], file)); m.Assert(e) { + defer o.Close() + + // 导入数据 + if n, e := o.Write(buf); m.Assert(e) { + m.Log(ice.LOG_IMPORT, "%s: %s", kit.FmtSize(int64(n)), p) + arg = kit.Simple(arg[0], arg[1], arg[2], p, p, n) + } + } + } + return arg +} + func init() { Index.Merge(&ice.Context{ Configs: map[string]*ice.Config{ - ice.WEB_CACHE: {Name: "cache", Help: "缓存池", Value: kit.Data( + CACHE: {Name: "cache", Help: "缓存池", Value: kit.Data( kit.MDB_SHORT, "text", "path", "var/file", "store", "var/data", "fsize", "100000", "limit", "50", "least", "30", )}, }, Commands: map[string]*ice.Command{ - ice.WEB_CACHE: {Name: "cache", Help: "缓存池", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + CACHE: {Name: "cache", Help: "缓存池", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { if len(arg) == 0 { - // 缓存记录 - m.Grows(ice.WEB_CACHE, nil, "", "", func(index int, value map[string]interface{}) { - m.Push("", value) - }) + _cache_list(m) return } switch arg[0] { case "catch": - // 导入文件 - if f, e := os.Open(arg[2]); m.Assert(e) { - defer f.Close() - - // 创建文件 - h := kit.Hashs(f) - if o, p, e := kit.Create(path.Join(m.Conf(ice.WEB_CACHE, "meta.path"), h[:2], h)); m.Assert(e) { - defer o.Close() - f.Seek(0, os.SEEK_SET) - - // 导入数据 - if n, e := io.Copy(o, f); m.Assert(e) { - m.Log(ice.LOG_IMPORT, "%s: %s", kit.FmtSize(n), p) - arg = kit.Simple(arg[0], arg[1], path.Base(arg[2]), p, p, n) - } - } - } + arg = _cache_catch(m, arg...) fallthrough case "upload", "download": if m.R != nil { - // 上传文件 - if f, h, e := m.R.FormFile(kit.Select("upload", arg, 1)); e == nil { - defer f.Close() - - // 创建文件 - file := kit.Hashs(f) - if o, p, e := kit.Create(path.Join(m.Conf(ice.WEB_CACHE, "meta.path"), file[:2], file)); m.Assert(e) { - defer o.Close() - f.Seek(0, os.SEEK_SET) - - // 导入数据 - if n, e := io.Copy(o, f); m.Assert(e) { - m.Log(ice.LOG_IMPORT, "%s: %s", kit.FmtSize(n), p) - arg = kit.Simple(arg[0], h.Header.Get("Content-Type"), h.Filename, p, p, n) - } - } - } + arg = _cache_upload(m, arg...) } else if r, ok := m.Optionv("response").(*http.Response); ok { - // 下载文件 - if buf, e := ioutil.ReadAll(r.Body); m.Assert(e) { - defer r.Body.Close() - - // 创建文件 - file := kit.Hashs(string(buf)) - if o, p, e := kit.Create(path.Join(m.Conf(ice.WEB_CACHE, "meta.path"), file[:2], file)); m.Assert(e) { - defer o.Close() - - // 导入数据 - if n, e := o.Write(buf); m.Assert(e) { - m.Log(ice.LOG_IMPORT, "%s: %s", kit.FmtSize(int64(n)), p) - arg = kit.Simple(arg[0], arg[1], arg[2], p, p, n) - } - } - } + arg = _cache_download(m, r, arg...) } fallthrough case "add": - size := kit.Int(kit.Select(kit.Format(len(arg[3])), arg, 5)) - if arg[0] == "add" && size > 512 { - // 创建文件 - file := kit.Hashs(arg[3]) - if o, p, e := kit.Create(path.Join(m.Conf(ice.WEB_CACHE, "meta.path"), file[:2], file)); m.Assert(e) { - defer o.Close() - - // 导入数据 - if n, e := o.WriteString(arg[3]); m.Assert(e) { - m.Log(ice.LOG_IMPORT, "%s: %s", kit.FmtSize(int64(n)), p) - arg = kit.Simple(arg[0], arg[1], arg[2], p, p, n) - } - } - } - - // 添加数据 - h := m.Rich(ice.WEB_CACHE, nil, kit.Dict( - kit.MDB_TYPE, arg[1], kit.MDB_NAME, arg[2], kit.MDB_TEXT, arg[3], - kit.MDB_FILE, kit.Select("", arg, 4), kit.MDB_SIZE, size, - )) - m.Log(ice.LOG_CREATE, "cache: %s %s: %s", h, arg[1], arg[2]) - - // 添加记录 - m.Grow(ice.WEB_CACHE, nil, kit.Dict( - kit.MDB_TYPE, arg[1], kit.MDB_NAME, arg[2], kit.MDB_TEXT, arg[3], - kit.MDB_SIZE, size, "data", h, - )) - - // 返回结果 - m.Push("time", m.Time()) - m.Push("type", arg[1]) - m.Push("name", arg[2]) - m.Push("text", arg[3]) - m.Push("size", size) - m.Push("data", h) + _cache_save(m, arg[0], arg[1], arg[2], arg[3], arg[4:]...) case "watch": - if m.Richs(ice.WEB_CACHE, nil, arg[1], func(key string, value map[string]interface{}) { - if value["file"] == "" { - if f, _, e := kit.Create(arg[2]); m.Assert(e) { - defer f.Close() - f.WriteString(kit.Format(value["text"])) - } - } else { - os.MkdirAll(path.Dir(arg[2]), 0777) - os.Remove(arg[2]) - os.Link(kit.Format(value["file"]), arg[2]) - } - }) == nil { - m.Cmdy(ice.WEB_SPIDE, "dev", "cache", "/cache/"+arg[1]) - os.MkdirAll(path.Dir(arg[2]), 0777) - os.Remove(arg[2]) - os.Link(m.Append("file"), arg[2]) - } - m.Echo(arg[2]) + _cache_show(m, arg[1], arg[2]) } }}, "/cache/": {Name: "/cache/", Help: "缓存池", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Richs(ice.WEB_CACHE, nil, arg[0], func(key string, value map[string]interface{}) { + m.Richs(CACHE, nil, arg[0], func(key string, value map[string]interface{}) { m.Render(ice.RENDER_DOWNLOAD, value["file"]) }) }}, diff --git a/base/web/share.go b/base/web/share.go index f87126b9..b94ee616 100644 --- a/base/web/share.go +++ b/base/web/share.go @@ -11,6 +11,166 @@ import ( "strings" ) +func _share_list(m *ice.Message, arg ...string) { + if len(arg) == 0 { + m.Grows(ice.WEB_SHARE, nil, "", "", func(index int, value map[string]interface{}) { + m.Push("", value, []string{kit.MDB_TIME, "share", kit.MDB_TYPE, kit.MDB_NAME, kit.MDB_TEXT}) + m.Push("value", fmt.Sprintf(m.Conf(ice.WEB_SHARE, "meta.template.link"), m.Conf(ice.WEB_SHARE, "meta.domain"), value["share"], value["share"])) + }) + return + } + + m.Richs(ice.WEB_SHARE, nil, arg[0], func(key string, value map[string]interface{}) { + m.Push("detail", value) + m.Push("key", "link") + m.Push("value", fmt.Sprintf(m.Conf(ice.WEB_SHARE, "meta.template.link"), m.Conf(ice.WEB_SHARE, "meta.domain"), key, key)) + m.Push("key", "share") + m.Push("value", fmt.Sprintf(m.Conf(ice.WEB_SHARE, "meta.template.share"), m.Conf(ice.WEB_SHARE, "meta.domain"), key)) + m.Push("key", "value") + m.Push("value", fmt.Sprintf(m.Conf(ice.WEB_SHARE, "meta.template.value"), m.Conf(ice.WEB_SHARE, "meta.domain"), key)) + }) +} + +func _share_auth(m *ice.Message, share string, role string) { + m.Richs(ice.WEB_SHARE, nil, share, func(key string, value map[string]interface{}) { + switch value["type"] { + case "active": + m.Cmdy(ice.WEB_SPACE, value["name"], "sessid", m.Cmdx(ice.AAA_SESS, "create", role)) + case "user": + m.Cmdy(ice.AAA_ROLE, role, value["name"]) + default: + m.Cmdy(ice.AAA_SESS, "auth", value["text"], role) + } + }) +} +func _share_check(m *ice.Message, share string) { + m.Richs(ice.WEB_SHARE, nil, share, func(key string, value map[string]interface{}) { + m.Render(ice.RENDER_QRCODE, kit.Format(kit.Dict( + kit.MDB_TYPE, "share", kit.MDB_NAME, value["type"], kit.MDB_TEXT, key, + ))) + }) +} +func _share_create(m *ice.Message, kind, name, text string, arg ...string) { + arg = append(arg, "storm", m.Option("storm"), "river", m.Option("river")) + h := m.Rich(ice.WEB_SHARE, nil, kit.Dict( + kit.MDB_TIME, m.Time(m.Conf(ice.WEB_SHARE, "meta.expire")), + kit.MDB_TYPE, kind, kit.MDB_NAME, name, kit.MDB_TEXT, text, + "extra", kit.Dict(arg), + )) + + // 创建列表 + m.Grow(ice.WEB_SHARE, nil, kit.Dict( + kit.MDB_TYPE, kind, kit.MDB_NAME, name, kit.MDB_TEXT, text, + "share", h, + )) + m.Logs(ice.LOG_CREATE, "share", h, "type", kind, "name", name) + m.Echo(h) +} + +func _share_local(m *ice.Message, arg ...string) { + p := path.Join(arg...) + switch ls := strings.Split(p, "/"); ls[0] { + case "etc", "var": + return + } + m.Render(ice.RENDER_DOWNLOAD, p) +} +func _share_repos(m *ice.Message, repos string, arg ...string) { + prefix := m.Conf(ice.WEB_SERVE, "meta.volcanos.require") + if _, e := os.Stat(path.Join(prefix, repos)); e != nil { + m.Cmd(ice.CLI_SYSTEM, "git", "clone", "https://"+repos, path.Join(prefix, repos)) + } + m.Render(ice.RENDER_DOWNLOAD, path.Join(prefix, repos, path.Join(arg...))) +} +func _share_remote(m *ice.Message, pod string, arg ...string) { + m.Cmdy(ice.WEB_SPACE, pod, "web./publish/", arg) + m.Render(ice.RENDER_RESULT) +} + +func _share_story(m *ice.Message, value map[string]interface{}, arg ...string) map[string]interface{} { + msg := m.Cmd(ice.WEB_STORY, ice.STORY_INDEX, value["text"]) + if msg.Append("text") == "" && kit.Value(value, "extra.pod") != "" { + msg = m.Cmd(ice.WEB_SPACE, kit.Value(value, "extra.pod"), ice.WEB_STORY, ice.STORY_INDEX, value["text"]) + } + value = kit.Dict("type", msg.Append("scene"), "name", msg.Append("story"), "text", msg.Append("text"), "file", msg.Append("file")) + m.Log(ice.LOG_EXPORT, "%s: %v", arg, kit.Format(value)) + return value +} +func _share_download(m *ice.Message, value map[string]interface{}) { + if strings.HasPrefix(kit.Format(value["text"]), m.Conf(ice.WEB_CACHE, "meta.path")) { + m.Render(ice.RENDER_DOWNLOAD, value["text"], value["type"], value["name"]) + } else { + m.Render("%s", value["text"]) + } +} + +func _share_action_redirect(m *ice.Message, value map[string]interface{}, share string) bool { + m.Render("redirect", "/share", "share", share, + "title", kit.Format(value["name"]), + "river", kit.Value(value, "extra.river"), + "storm", kit.Value(value, "extra.storm"), + ) + return true +} +func _share_action_page(m *ice.Message, value map[string]interface{}) bool { + Render(m, ice.RENDER_DOWNLOAD, m.Conf(ice.WEB_SERVE, "meta.page.share")) + return true +} +func _share_action_list(m *ice.Message, value map[string]interface{}, river, storm string) bool { + value["count"] = kit.Int(value["count"]) + 1 + kit.Fetch(kit.Value(value, "extra.tool"), func(index int, value map[string]interface{}) { + m.Push("river", river) + m.Push("storm", storm) + m.Push("action", index) + + m.Push("node", value["pod"]) + m.Push("group", value["ctx"]) + m.Push("index", value["cmd"]) + m.Push("args", value["args"]) + + msg := m.Cmd(m.Space(value["pod"]), ice.CTX_COMMAND, value["ctx"], value["cmd"]) + m.Push("name", value["cmd"]) + m.Push("help", kit.Select(msg.Append("help"), kit.Format(value["help"]))) + m.Push("inputs", msg.Append("list")) + m.Push("feature", msg.Append("meta")) + }) + return true +} +func _share_action(m *ice.Message, value map[string]interface{}, arg ...string) bool { + if len(arg) == 1 { + return _share_action_redirect(m, value, arg[0]) + } + if arg[1] == "" { + return _share_action_page(m, value) + } + if len(arg) == 2 { + return _share_action_list(m, value, arg[0], arg[1]) + } + + // 默认参数 + meta := kit.Value(value, kit.Format("extra.tool.%s", arg[2])).(map[string]interface{}) + if meta["single"] == "yes" && kit.Select("", arg, 3) != "action" { + arg = append(arg[:3], kit.Simple(kit.UnMarshal(kit.Format(meta["args"])))...) + for i := len(arg) - 1; i >= 0; i-- { + if arg[i] != "" { + return true + } + arg = arg[:i] + } + } + + // 执行命令 + cmds := kit.Simple(m.Space(meta["pod"]), kit.Keys(meta["ctx"], meta["cmd"]), arg[3:]) + m.Cmdy(cmds).Option("cmds", cmds) + m.Option("title", value["name"]) + if strings.HasPrefix(kit.Format(value["text"]), m.Conf(ice.WEB_CACHE, "meta.path")) { + m.Render(ice.RENDER_DOWNLOAD, value["text"], value["type"], value["name"]) + } else { + m.Render("%s", value["text"]) + } + return true +} + func init() { Index.Merge(&ice.Context{ Configs: map[string]*ice.Config{ @@ -23,80 +183,33 @@ func init() { Commands: map[string]*ice.Command{ ice.WEB_SHARE: {Name: "share share auto", Help: "共享链", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { if len(arg) == 0 { - // 共享列表 - m.Grows(ice.WEB_SHARE, nil, "", "", func(index int, value map[string]interface{}) { - m.Push("", value, []string{kit.MDB_TIME, "share", kit.MDB_TYPE, kit.MDB_NAME, kit.MDB_TEXT}) - m.Push("value", fmt.Sprintf(m.Conf(ice.WEB_SHARE, "meta.template.link"), m.Conf(ice.WEB_SHARE, "meta.domain"), value["share"], value["share"])) - }) + _share_list(m) return } - if len(arg) == 1 { - // 共享详情 - if m.Richs(ice.WEB_SHARE, nil, arg[0], func(key string, value map[string]interface{}) { - m.Push("detail", value) - m.Push("key", "link") - m.Push("value", fmt.Sprintf(m.Conf(ice.WEB_SHARE, "meta.template.link"), m.Conf(ice.WEB_SHARE, "meta.domain"), key, key)) - m.Push("key", "share") - m.Push("value", fmt.Sprintf(m.Conf(ice.WEB_SHARE, "meta.template.share"), m.Conf(ice.WEB_SHARE, "meta.domain"), key)) - m.Push("key", "value") - m.Push("value", fmt.Sprintf(m.Conf(ice.WEB_SHARE, "meta.template.value"), m.Conf(ice.WEB_SHARE, "meta.domain"), key)) - }) != nil { - return - } - } switch arg[0] { case "invite": arg = []string{arg[0], m.Cmdx(ice.WEB_SHARE, "add", "invite", kit.Select("tech", arg, 1), kit.Select("miss", arg, 2))} - fallthrough case "check": - m.Richs(ice.WEB_SHARE, nil, arg[1], func(key string, value map[string]interface{}) { - m.Render(ice.RENDER_QRCODE, kit.Format(kit.Dict( - kit.MDB_TYPE, "share", kit.MDB_NAME, value["type"], kit.MDB_TEXT, key, - ))) - }) - + _share_check(m, arg[1]) case "auth": - m.Richs(ice.WEB_SHARE, nil, arg[1], func(key string, value map[string]interface{}) { - switch value["type"] { - case "active": - m.Cmdy(ice.WEB_SPACE, value["name"], "sessid", m.Cmdx(ice.AAA_SESS, "create", arg[2])) - case "user": - m.Cmdy(ice.AAA_ROLE, arg[2], value["name"]) - default: - m.Cmdy(ice.AAA_SESS, "auth", value["text"], arg[2]) - } - }) - + _share_auth(m, arg[1], arg[2]) case "add": - arg = arg[1:] - fallthrough + _share_create(m, arg[1], arg[2], arg[3], arg[4:]...) default: - if len(arg) == 2 { - arg = append(arg, "") + if len(arg) == 1 { + _share_list(m, arg[0]) + break } - extra := kit.Dict(arg[3:]) - - // 创建共享 - h := m.Rich(ice.WEB_SHARE, nil, kit.Dict( - kit.MDB_TIME, m.Time(m.Conf(ice.WEB_SHARE, "meta.expire")), - kit.MDB_TYPE, arg[0], kit.MDB_NAME, arg[1], kit.MDB_TEXT, arg[2], - "extra", extra, - )) - // 创建列表 - m.Grow(ice.WEB_SHARE, nil, kit.Dict( - kit.MDB_TYPE, arg[0], kit.MDB_NAME, arg[1], kit.MDB_TEXT, arg[2], - "share", h, - )) - m.Log(ice.LOG_CREATE, "share: %s extra: %s", h, kit.Format(extra)) - m.Echo(h) + _share_create(m, arg[0], arg[1], arg[2], arg[3:]...) } }}, "/share/": {Name: "/share/", Help: "共享链", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + m.Log(ice.LOG_EXPORT, "%s: %v", arg, arg) switch arg[0] { case "local": - m.Render(ice.RENDER_DOWNLOAD, m.Cmdx(arg[1], path.Join(arg[2:]...))) + _share_local(m, arg[1:]...) return } @@ -110,22 +223,12 @@ func init() { switch value["type"] { case ice.TYPE_SPACE: case ice.TYPE_STORY: - // 查询数据 - msg := m.Cmd(ice.WEB_STORY, ice.STORY_INDEX, value["text"]) - if msg.Append("text") == "" && kit.Value(value, "extra.pod") != "" { - msg = m.Cmd(ice.WEB_SPACE, kit.Value(value, "extra.pod"), ice.WEB_STORY, ice.STORY_INDEX, value["text"]) - } - value = kit.Dict("type", msg.Append("scene"), "name", msg.Append("story"), "text", msg.Append("text"), "file", msg.Append("file")) - m.Log(ice.LOG_EXPORT, "%s: %v", arg, kit.Format(value)) + value = _share_story(m, value, arg...) } switch kit.Select("", arg, 1) { case "download", "下载": - if strings.HasPrefix(kit.Format(value["text"]), m.Conf(ice.WEB_CACHE, "meta.path")) { - m.Render(ice.RENDER_DOWNLOAD, value["text"], value["type"], value["name"]) - } else { - m.Render("%s", value["text"]) - } + _share_download(m, value) return case "detail", "详情": m.Render(kit.Formats(value)) @@ -156,57 +259,7 @@ func init() { m.Render("redirect", "/", "share", key, "storm", kit.Format(value["text"]), "river", kit.Format(kit.Value(value, "extra.river"))) case ice.TYPE_ACTION: - if len(arg) == 1 { - // 跳转主页 - m.Render("redirect", "/share", "share", arg[0], "title", kit.Format(value["name"])) - break - } - - if arg[1] == "" { - // 返回主页 - Render(m, ice.RENDER_DOWNLOAD, m.Conf(ice.WEB_SERVE, "meta.page.share")) - break - } - - if len(arg) == 2 { - // 应用列表 - value["count"] = kit.Int(value["count"]) + 1 - kit.Fetch(kit.Value(value, "extra.tool"), func(index int, value map[string]interface{}) { - m.Push("river", arg[0]) - m.Push("storm", arg[1]) - m.Push("action", index) - - m.Push("node", value["pod"]) - m.Push("group", value["ctx"]) - m.Push("index", value["cmd"]) - m.Push("args", value["args"]) - - msg := m.Cmd(m.Space(value["pod"]), ice.CTX_COMMAND, value["ctx"], value["cmd"]) - m.Push("name", value["cmd"]) - m.Push("help", kit.Select(msg.Append("help"), kit.Format(value["help"]))) - m.Push("inputs", msg.Append("list")) - m.Push("feature", msg.Append("meta")) - }) - break - } - - // 默认参数 - meta := kit.Value(value, kit.Format("extra.tool.%s", arg[2])).(map[string]interface{}) - if meta["single"] == "yes" && kit.Select("", arg, 3) != "action" { - arg = append(arg[:3], kit.Simple(kit.UnMarshal(kit.Format(meta["args"])))...) - for i := len(arg) - 1; i >= 0; i-- { - if arg[i] != "" { - break - } - arg = arg[:i] - } - } - - // 执行命令 - cmds := kit.Simple(m.Space(meta["pod"]), kit.Keys(meta["ctx"], meta["cmd"]), arg[3:]) - m.Cmdy(cmds).Option("cmds", cmds) - m.Option("title", value["name"]) - + _share_action(m, value, arg...) default: // 查看数据 m.Option("type", value["type"]) @@ -218,18 +271,12 @@ func init() { }) }}, "/plugin/github.com/": {Name: "/space/", Help: "空间站", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - prefix := m.Conf(ice.WEB_SERVE, "meta.volcanos.require") - repos := path.Join(strings.Split(cmd, "/")[2:5]...) - if _, e := os.Stat(path.Join(prefix, repos)); e != nil { - m.Cmd(ice.CLI_SYSTEM, "git", "clone", "https://"+repos, path.Join(prefix, repos)) - } - m.Render(ice.RENDER_DOWNLOAD, path.Join(prefix, repos, path.Join(arg[2:]...))) + _share_repos(m, path.Join(strings.Split(cmd, "/")[2:5]...), arg[6:]...) }}, "/publish/": {Name: "/publish/", Help: "空间站", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { if p := m.Option("pod"); p != "" { m.Option("pod", "") - m.Cmdy(ice.WEB_SPACE, p, "web./publish/", arg) - m.Render(ice.RENDER_RESULT) + _share_remote(m, p, arg...) return } @@ -238,14 +285,7 @@ func init() { m.Cmdy("nfs.cat", p) return } - m.Render(ice.RENDER_DOWNLOAD, p) - }}, - "/local/": {Name: "/space/", Help: "空间站", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - p := path.Join(cmd) - switch strings.TrimSuffix(path.Ext(p), ".") { - case "js": - m.Render(ice.RENDER_DOWNLOAD, p) - } + _share_local(m, p) }}, }}, nil) } diff --git a/base/web/story.go b/base/web/story.go index 28189c70..4c410919 100644 --- a/base/web/story.go +++ b/base/web/story.go @@ -228,12 +228,12 @@ func _story_trash(m *ice.Message, arg ...string) { os.Remove(bak) os.Rename(arg[1], bak) } -func _story_watch(m *ice.Message, arg ...string) { +func _story_watch(m *ice.Message, index string, arg ...string) { // 备份文件 - name := kit.Select(arg[1], arg, 2) + name := kit.Select(index, arg, 0) m.Cmd(ice.WEB_STORY, ice.STORY_TRASH, name) - if msg := m.Cmd(ice.WEB_STORY, ice.STORY_INDEX, arg[1]); msg.Append("file") != "" { + if msg := m.Cmd(ice.WEB_STORY, ice.STORY_INDEX, index); msg.Append("file") != "" { p := path.Dir(name) os.MkdirAll(p, 0777) @@ -305,36 +305,37 @@ func _story_add(m *ice.Message, arg ...string) { // 分发数据 if p := kit.Select(m.Conf(ice.WEB_FAVOR, "meta.proxy"), m.Option("you")); p != "" { - m.Info("what %v", p) m.Option("you", "") m.Cmd(ice.WEB_PROXY, p, ice.WEB_STORY, ice.STORY_PULL, arg[2], "dev", arg[2]) } } -func _story_index(m *ice.Message, arg ...string) { - m.Richs(ice.WEB_STORY, "head", arg[1], func(key string, value map[string]interface{}) { +func _story_index(m *ice.Message, name string) { + m.Richs(ice.WEB_STORY, "head", name, func(key string, value map[string]interface{}) { // 查询索引 - arg[1] = kit.Format(value["list"]) + name = kit.Format(value["list"]) }) - m.Richs(ice.WEB_STORY, nil, arg[1], func(key string, value map[string]interface{}) { + m.Richs(ice.WEB_STORY, nil, name, func(key string, value map[string]interface{}) { // 查询节点 m.Push("list", key) m.Push(key, value, []string{"scene", "story"}) - arg[1] = kit.Format(value["data"]) + name = kit.Format(value["data"]) }) - m.Richs(ice.WEB_CACHE, nil, arg[1], func(key string, value map[string]interface{}) { + m.Richs(ice.WEB_CACHE, nil, name, func(key string, value map[string]interface{}) { // 查询数据 m.Push("data", key) m.Push(key, value, []string{"text", "time", "size", "type", "name", "file"}) - m.Echo("%s", value["text"]) + if value["file"] != "" { + m.Echo("%s", m.Cmdx("nfs.cat", value["file"])) + } }) } -func _story_history(m *ice.Message, arg ...string) { +func _story_history(m *ice.Message, name string) { // 历史记录 - list := m.Cmd(ice.WEB_STORY, ice.STORY_INDEX, arg[1]).Append("list") + list := m.Cmd(ice.WEB_STORY, ice.STORY_INDEX, name).Append("list") for i := 0; i < kit.Int(kit.Select("30", m.Option("cache.limit"))) && list != ""; i++ { m.Richs(ice.WEB_STORY, nil, list, func(key string, value map[string]interface{}) { @@ -362,7 +363,9 @@ func _story_history(m *ice.Message, arg ...string) { } } -func StoryWatch(m *ice.Message, file string, name string) { _story_watch(m, file, name) } +func StoryIndex(m *ice.Message, name string) { _story_index(m, name) } +func StoryHistory(m *ice.Message, name string) { _story_history(m, name) } +func StoryWatch(m *ice.Message, index string, file string) { _story_watch(m, index, file) } func StoryCatch(m *ice.Message, mime string, file string) { _story_catch(m, "catch", kit.Select(mime, strings.TrimPrefix(path.Ext(file), ".")), file) } @@ -413,16 +416,16 @@ func init() { case ice.STORY_TRASH: _story_trash(m, arg...) case ice.STORY_WATCH: - _story_watch(m, arg...) + _story_watch(m, arg[1], arg[2:]...) case ice.STORY_CATCH: _story_catch(m, arg...) case "add", ice.STORY_UPLOAD, ice.STORY_DOWNLOAD: _story_add(m, arg...) case ice.STORY_INDEX: - _story_index(m, arg...) + _story_index(m, arg[1]) case ice.STORY_HISTORY: - _story_history(m, arg...) + _story_history(m, arg[1]) default: _story_show(m, arg...) } diff --git a/core/chat/action.go b/core/chat/action.go index 69ec8e81..a0babbf3 100644 --- a/core/chat/action.go +++ b/core/chat/action.go @@ -45,6 +45,10 @@ func _action_share_select(m *ice.Message, c *ice.Context, cmd string, arg ...str }) } func _action_share_update(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + if len(arg) > 3 && arg[3] == "action" && _action_action(m, arg[4], arg[5:]...) { + return + } + m.Richs(ice.WEB_SHARE, nil, m.Option("share"), func(key string, value map[string]interface{}) { kit.Fetch(kit.Value(value, kit.Keys("extra.tool", arg[2])), func(value map[string]interface{}) { cmds := kit.Simple(m.Space(value["pod"]), kit.Keys(value["ctx"], value["cmd"]), arg[3:]) @@ -60,7 +64,21 @@ func _action_proxy(m *ice.Message) (proxy []string) { } return proxy } +func _action_action(m *ice.Message, action string, arg ...string) bool { + switch action { + case "upload": + msg := m.Cmd(ice.WEB_STORY, "upload") + m.Option("name", msg.Append("name")) + m.Option("data", msg.Append("data")) + } + return false +} + func _action_order(m *ice.Message, arg ...string) { + if len(arg) > 3 && arg[3] == "action" && _action_action(m, arg[4], arg[5:]...) { + return + } + cmds := kit.Simple(kit.Keys(m.Option("group"), m.Option("index")), arg[3:]) if m.Set(ice.MSG_RESULT); !m.Right(cmds) { m.Render("status", 403, "not auth") @@ -99,6 +117,7 @@ func init() { _action_share_create(m, arg...) return } + if len(arg) == 0 || arg[0] == "" { if m.Option("share") != "" { if len(arg) < 3 { diff --git a/core/wiki/inner.go b/core/wiki/inner.go index 53f5f704..45a27e69 100644 --- a/core/wiki/inner.go +++ b/core/wiki/inner.go @@ -7,9 +7,30 @@ import ( "os" "path" + "strings" ) +const INNER = "inner" +const QRCODE = "qrcode" +const VEDIO = "vedio" + +func _inner_list(m *ice.Message, name string) { + if ls := strings.Split(name, "/"); m.Conf(INNER, kit.Keys("meta.protect", ls[0])) == "true" { + m.Push("file", "../") + return + } + + if m.Cmdy(kit.Keys(strings.TrimPrefix(path.Ext(name), "."), "list"), name); len(m.Resultv()) > 0 { + return + } + + m.Cmdy("nfs.dir", name, "file") +} func _inner_save(m *ice.Message, name, text string) { + if m.Cmdy(kit.Keys(strings.TrimPrefix(path.Ext(name), "."), "save"), name, text); len(m.Resultv()) > 0 { + return + } + if f, e := os.Create(name); m.Assert(e) { defer f.Close() if n, e := f.WriteString(text); m.Assert(e) { @@ -17,37 +38,104 @@ func _inner_save(m *ice.Message, name, text string) { } } } +func _inner_plug(m *ice.Message, name string) { + p := strings.TrimPrefix(path.Ext(name), ".") + if msg := m.Cmd(kit.Keys(p, "plug"), name); m != msg && msg.Hand { + m.Copy(msg) + return + } + + if ls := m.Confv(INNER, kit.Keys("meta.plug", p)); ls != nil { + m.Echo(kit.Format(ls)) + return + } + + m.Echo("{}") +} +func _inner_show(m *ice.Message, name string) { + p := strings.TrimPrefix(path.Ext(name), ".") + if msg := m.Cmd(kit.Keys(p, "show"), name); m != msg && msg.Hand { + m.Copy(msg) + return + } + + if ls := kit.Simple(m.Confv(INNER, kit.Keys("meta.show", p))); len(ls) > 0 { + m.Cmdy(ice.CLI_SYSTEM, ls, name) + m.Set(ice.MSG_APPEND) + return + } + + switch p { + case "csv": + m.CSV(m.Cmdx("nfs.cat", name)) + case "md": + m.Cmdy("web.wiki.md.note", name) + case "shy": + m.Echo(strings.ReplaceAll(strings.Join(m.Cmd("web.wiki.word", name).Resultv(), ""), "\n", " ")) + } +} func init() { - const ( - INNER = "inner" - SAVE = "save" - COMMIT = "commit" - ) - Index.Merge(&ice.Context{ Configs: map[string]*ice.Config{ - INNER: {Name: "inner", Help: "编辑器", Value: kit.Data(kit.MDB_SHORT, INNER)}, + INNER: {Name: "inner", Help: "编辑器", Value: kit.Data( + "protect", kit.Dict("etc", "true", "var", "true", "usr", "true"), + "plug", kit.Dict( + "py", kit.Dict("display", true, "profile", true), + "md", kit.Dict("display", true, "profile", true), + "csv", kit.Dict("display", true), + ), + "show", kit.Dict( + "sh", []string{"bash"}, + "py", []string{"python"}, + "go", []string{"go", "run"}, + "js", []string{"node"}, + ), + kit.MDB_SHORT, INNER, + )}, }, Commands: map[string]*ice.Command{ - INNER: {Name: "inner path=auto auto", Help: "编辑器", Action: map[string]*ice.Action{ - SAVE: {Name: "save name content", Help: "保存", Hand: func(m *ice.Message, arg ...string) { - _inner_save(m, arg[0], kit.Select(m.Option("content"), arg, 1)) - }}, - COMMIT: {Name: "commit name", Help: "提交", Hand: func(m *ice.Message, arg ...string) { - web.StoryCatch(m, "", arg[0]) - }}, - "go": {Name: "go name", Help: "提交", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(ice.CLI_SYSTEM, "go", "run", path.Join("./", arg[0])) - }}, - "project": {Name: "go name", Help: "提交", Hand: func(m *ice.Message, arg ...string) { - if len(arg) == 0 || arg[0] == "" { - arg = append(arg, "./") + INNER: {Name: "inner path=auto name=auto auto", Help: "编辑器", Meta: map[string]interface{}{ + "display": "/plugin/inner.js", "style": "editor", + }, Action: map[string]*ice.Action{ + "history": {Name: "history path name", Help: "历史", Hand: func(m *ice.Message, arg ...string) { + web.StoryHistory(m, path.Join("./", arg[0], arg[1])) + if len(arg) > 2 && arg[2] != "" { + m.Echo(m.Cmdx(ice.WEB_STORY, "index", arg[2])) } - m.Cmdy("nfs.dir", path.Join(arg...), "file") + }}, + "commit": {Name: "commit path name", Help: "提交", Hand: func(m *ice.Message, arg ...string) { + web.StoryCatch(m, "", path.Join("./", arg[0], arg[1])) + }}, + + "run": {Name: "run path name", Help: "运行", Hand: func(m *ice.Message, arg ...string) { + _inner_show(m, path.Join("./", arg[0], arg[1])) + }}, + "plug": {Name: "plug path name", Help: "插件", Hand: func(m *ice.Message, arg ...string) { + _inner_plug(m, path.Join("./", arg[0], arg[1])) + }}, + "save": {Name: "save path name content", Help: "保存", Hand: func(m *ice.Message, arg ...string) { + _inner_save(m, path.Join("./", arg[0], arg[1]), kit.Select(m.Option("content"), arg, 2)) + }}, + "upload": {Name: "upload path name", Help: "上传", Hand: func(m *ice.Message, arg ...string) { + web.StoryWatch(m, m.Option("data"), path.Join(m.Option("path"), m.Option("name"))) + }}, + "project": {Name: "project path", Help: "项目", Hand: func(m *ice.Message, arg ...string) { + _inner_list(m, path.Join("./", kit.Select("", arg, 0))) }}, }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Cmdy("nfs.dir", path.Join(arg...), "file") + if len(arg) > 0 && arg[0] == "action" { + if m.Cmdy(kit.Split(arg[1])); !m.Hand { + m.Cmdy(ice.CLI_SYSTEM, kit.Split(arg[1])) + } + return + } + + if len(arg) > 2 && arg[2] != "" { + m.Echo(m.Cmdx(ice.WEB_STORY, "index", arg[2])) + return + } + _inner_list(m, path.Join(arg...)) }}, }, }, nil) diff --git a/core/wiki/qrcode.go b/core/wiki/qrcode.go new file mode 100644 index 00000000..ab35896d --- /dev/null +++ b/core/wiki/qrcode.go @@ -0,0 +1,47 @@ +package wiki + +import ( + ice "github.com/shylinux/icebergs" + kit "github.com/shylinux/toolkits" + + qrs "github.com/skip2/go-qrcode" + "github.com/tuotoo/qrcode" + "os" +) + +func init() { + Index.Register(&ice.Context{Name: "qrc", Help: "二维码", + Configs: map[string]*ice.Config{ + QRCODE: {Name: "qrcode", Help: "二维码", Value: kit.Data( + "plug", `{"display": {"height": "400px"}}`, + )}, + }, + Commands: map[string]*ice.Command{ + "list": {Name: "list name", Help: "列表", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + if f, e := os.Open(arg[0]); e == nil { + defer f.Close() + if q, e := qrcode.Decode(f); e == nil { + m.Echo(q.Content) + return + } + } + m.Echo("hello world") + }}, + "save": {Name: "save name text", Help: "保存", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + if qr, e := qrs.New(arg[1], qrs.Medium); m.Assert(e) { + if f, e := os.Create(arg[0]); m.Assert(e) { + defer f.Close() + m.Assert(qr.Write(kit.Int(kit.Select("256", arg, 2)), f)) + m.Echo(arg[0]) + } + } + }}, + "plug": {Name: "plug name text", Help: "插件", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + m.Echo(m.Conf(QRCODE, "meta.plug")) + }}, + "show": {Name: "show name", Help: "渲染", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + m.Echo(``, arg[0]) + }}, + }, + }, nil) +} diff --git a/core/wiki/video b/core/wiki/video new file mode 100644 index 00000000..3db7f700 --- /dev/null +++ b/core/wiki/video @@ -0,0 +1,2 @@ +package wiki + diff --git a/core/wiki/video.go b/core/wiki/video.go new file mode 100644 index 00000000..22979bb0 --- /dev/null +++ b/core/wiki/video.go @@ -0,0 +1,50 @@ +package wiki + +import ( + ice "github.com/shylinux/icebergs" + kit "github.com/shylinux/toolkits" + + "github.com/nareix/joy4/av" + "github.com/nareix/joy4/av/avutil" + "github.com/nareix/joy4/codec/h264parser" +) + +func init() { + format.RegisterAll() + + Index.Register(&ice.Context{Name: "m4v", Help: "视频", + Configs: map[string]*ice.Config{ + VEDIO: {Name: "vedio", Help: "视频", Value: kit.Data()}, + }, + Commands: map[string]*ice.Command{ + "list": {Name: "list name", Help: "列表", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + m.Echo(arg[0]) + }}, + "save": {Name: "save name text", Help: "保存", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + m.Cmdy("nfs.qrcodes", arg) + }}, + "show": {Name: "show name", Help: "渲染", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + if file, e := avutil.Open(arg[0]); m.Assert(e) { + if streams, e := file.Streams(); m.Assert(e) { + for _, stream := range streams { + m.Info("what %v", kit.Formats(stream)) + + if stream.Type().IsAudio() { + } else if stream.Type().IsVideo() { + + m.Info("what %v", kit.Formats(stream)) + h264parser.ParseSPS(stream.RecordInfo.SPS) + + vstream := stream.(av.VideoCodecData) + m.Push("type", vstream.Type().String()) + m.Push("width", vstream.Width()) + m.Push("height", vstream.Height()) + } + } + } + } + }}, + }, + }, nil) + +} diff --git a/go.mod b/go.mod index bea17ea1..a69471d2 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,8 @@ go 1.13 require ( github.com/gorilla/websocket v1.4.1 + github.com/nareix/joy4 v0.0.0-20200507095837-05a4ffbb5369 // indirect github.com/shylinux/toolkits v0.1.5 github.com/skip2/go-qrcode v0.0.0-20191027152451-9434209cb086 + github.com/tuotoo/qrcode v0.0.0-20190222102259-ac9c44189bf2 ) diff --git a/go.sum b/go.sum index 50d8aef0..1f68e8c1 100644 --- a/go.sum +++ b/go.sum @@ -1,8 +1,16 @@ +github.com/google/uuid v1.1.0 h1:Jf4mxPC/ziBnoPIdpQdPJ9OeiomAUHLvxmPRSPH9m4s= +github.com/google/uuid v1.1.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/maruel/rs v0.0.0-20150922171536-2c81c4312fe4 h1:u9jwvcKbQpghIXgNl/EOL8hzhAFXh4ePrEP493W3tNA= +github.com/maruel/rs v0.0.0-20150922171536-2c81c4312fe4/go.mod h1:kcRFpEzolcEklV6rD7W95mG49/sbdX/PlFmd7ni3RvA= +github.com/nareix/joy4 v0.0.0-20200507095837-05a4ffbb5369 h1:Yp0zFEufLz0H7jzffb4UPXijavlyqlYeOg7dcyVUNnQ= +github.com/nareix/joy4 v0.0.0-20200507095837-05a4ffbb5369/go.mod h1:aFJ1ZwLjvHN4yEzE5Bkz8rD8/d8Vlj3UIuvz2yfET7I= github.com/shylinux/toolkits v0.1.4 h1:GW7rRFOSww56x+rUfH0/tho3+FaErxz5+5RwlA8oWnk= github.com/shylinux/toolkits v0.1.4/go.mod h1:Y68Ot6xOmo1bun67YvqC3chDGeU2gDxtsUnvVDGJm4g= github.com/shylinux/toolkits v0.1.5 h1:rGLsEGuPzuib/sOZXCbF8D+JGjqeQJ+a1rX/G6/sc8w= github.com/shylinux/toolkits v0.1.5/go.mod h1:Y68Ot6xOmo1bun67YvqC3chDGeU2gDxtsUnvVDGJm4g= github.com/skip2/go-qrcode v0.0.0-20191027152451-9434209cb086 h1:RYiqpb2ii2Z6J4x0wxK46kvPBbFuZcdhS+CIztmYgZs= github.com/skip2/go-qrcode v0.0.0-20191027152451-9434209cb086/go.mod h1:PLPIyL7ikehBD1OAjmKKiOEhbvWyHGaNDjquXMcYABo= +github.com/tuotoo/qrcode v0.0.0-20190222102259-ac9c44189bf2 h1:BWVtt2VBY+lmVDu9MGKqLGKl04B+iRHcrW1Ptyi/8tg= +github.com/tuotoo/qrcode v0.0.0-20190222102259-ac9c44189bf2/go.mod h1:lPnW9HVS0vJdeYyQtOvIvlXgZPNhUAhwz+z5r8AJk0Y= diff --git a/misc/md/md.go b/misc/md/md.go index 64a1c5c7..ebf3c26a 100644 --- a/misc/md/md.go +++ b/misc/md/md.go @@ -7,7 +7,8 @@ import ( "github.com/gomarkdown/markdown" "io/ioutil" - "math/rand" + "path" + "strings" ) var Index = &ice.Context{Name: "md", Help: "md", diff --git a/name.go b/name.go new file mode 100644 index 00000000..c5c6636e --- /dev/null +++ b/name.go @@ -0,0 +1,17 @@ +package ice + +import ( + "errors" +) + +var names = map[string]interface{}{} + +var ErrNameExists = errors.New("name already exists") + +func Name(name string, value interface{}) string { + if _, ok := names[name]; ok { + panic(ErrNameExists) + } + names[name] = value + return name +} diff --git a/type.go b/type.go index 41f4b5c4..1a7aac52 100644 --- a/type.go +++ b/type.go @@ -79,15 +79,19 @@ func (c *Context) Cap(key string, arg ...interface{}) string { return c.Caches[key].Value } func (c *Context) Run(m *Message, cmd *Command, key string, arg ...string) *Message { + action, args := m.Option("_action"), arg + if len(arg) > 0 && arg[0] == "action" { + action, args = arg[1], arg[2:] + } m.Log(LOG_CMDS, "%s.%s %d %v", c.Name, key, len(arg), arg) - if m.Hand = true; len(arg) > 1 && arg[0] == "action" && cmd.Action != nil { - if h, ok := cmd.Action[arg[1]]; ok { - h.Hand(m, arg[2:]...) + if m.Hand = true; len(arg) > 1 && action != "" && cmd.Action != nil { + if h, ok := cmd.Action[action]; ok { + h.Hand(m, args...) return m } for _, h := range cmd.Action { - if h.Name == arg[1] || h.Help == arg[1] { - h.Hand(m, arg[2:]...) + if h.Name == action || h.Help == action { + h.Hand(m, args...) return m } } @@ -140,6 +144,12 @@ func (c *Context) Spawn(m *Message, name string, help string, arg ...string) *Co return s } func (c *Context) Begin(m *Message, arg ...string) *Context { + if c.Caches == nil { + c.Caches = map[string]*Cache{} + } + if c.Configs == nil { + c.Configs = map[string]*Config{} + } c.Caches[CTX_FOLLOW] = &Cache{Name: CTX_FOLLOW, Value: ""} c.Caches[CTX_STREAM] = &Cache{Name: CTX_STREAM, Value: ""} c.Caches[CTX_STATUS] = &Cache{Name: CTX_STATUS, Value: ""} @@ -677,7 +687,7 @@ func (m *Message) Cmd(arg ...interface{}) *Message { }) if m.Warn(m.Hand == false, "not found %v", list) { - return m.Set(MSG_RESULT).Cmd(CLI_SYSTEM, list) + // return m.Set(MSG_RESULT).Cmd(CLI_SYSTEM, list) } return m }