diff --git a/base/web/cache.go b/base/web/cache.go new file mode 100644 index 00000000..7ec84bc2 --- /dev/null +++ b/base/web/cache.go @@ -0,0 +1,153 @@ +package web + +import ( + "io" + "io/ioutil" + "net/http" + "path" + + ice "github.com/shylinux/icebergs" + kit "github.com/shylinux/toolkits" + + "os" +) + +func init() { + Index.Merge(&ice.Context{ + Configs: map[string]*ice.Config{ + ice.WEB_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) { + if len(arg) == 0 { + // 缓存记录 + m.Grows(ice.WEB_CACHE, nil, "", "", func(index int, value map[string]interface{}) { + m.Push("", value) + }) + 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) + } + } + } + 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) + } + } + } + } 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) + } + } + } + } + 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) + 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/": {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.Render(ice.RENDER_DOWNLOAD, value["file"]) + }) + }}, + }}, nil) +} diff --git a/base/web/favor.go b/base/web/favor.go new file mode 100644 index 00000000..7fb25837 --- /dev/null +++ b/base/web/favor.go @@ -0,0 +1,236 @@ +package web + +import ( + "encoding/csv" + + ice "github.com/shylinux/icebergs" + kit "github.com/shylinux/toolkits" + + "os" +) + +func init() { + Index.Merge(&ice.Context{ + Configs: map[string]*ice.Config{ + ice.WEB_FAVOR: {Name: "favor", Help: "收藏夹", Value: kit.Data( + kit.MDB_SHORT, kit.MDB_NAME, "template", favor_template, + "proxy", "", + )}, + }, + Commands: map[string]*ice.Command{ + ice.WEB_FAVOR: {Name: "favor favor=auto id=auto auto", Help: "收藏夹", Meta: kit.Dict( + "exports", []string{"hot", "favor"}, "detail", []string{"编辑", "收藏", "收录", "导出", "删除"}, + ), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + if len(arg) > 1 && arg[0] == "action" { + favor, id := m.Option("favor"), m.Option("id") + switch arg[2] { + case "favor": + favor = arg[3] + case "id": + id = arg[3] + } + + switch arg[1] { + case "modify", "编辑": + m.Richs(ice.WEB_FAVOR, nil, favor, func(key string, value map[string]interface{}) { + if id == "" { + m.Log(ice.LOG_MODIFY, "favor: %s value: %v->%v", key, kit.Value(value, kit.Keys("meta", arg[2])), arg[3]) + m.Echo("%s->%s", kit.Value(value, kit.Keys("meta", arg[2])), arg[3]) + kit.Value(value, kit.Keys("meta", arg[2]), arg[3]) + return + } + m.Grows(ice.WEB_FAVOR, kit.Keys(kit.MDB_HASH, key), "id", id, func(index int, value map[string]interface{}) { + m.Log(ice.LOG_MODIFY, "favor: %s index: %d value: %v->%v", key, index, value[arg[2]], arg[3]) + m.Echo("%s->%s", value[arg[2]], arg[3]) + kit.Value(value, arg[2], arg[3]) + }) + }) + case "commit", "收录": + m.Echo("list: ") + m.Richs(ice.WEB_FAVOR, nil, favor, func(key string, value map[string]interface{}) { + m.Grows(ice.WEB_FAVOR, kit.Keys(kit.MDB_HASH, key), "id", id, func(index int, value map[string]interface{}) { + m.Cmdy(ice.WEB_STORY, "add", value["type"], value["name"], value["text"]) + }) + }) + case "export", "导出": + m.Echo("list: ") + if favor == "" { + m.Cmdy(ice.MDB_EXPORT, ice.WEB_FAVOR, kit.MDB_HASH, kit.MDB_HASH, "favor") + } else { + m.Richs(ice.WEB_FAVOR, nil, favor, func(key string, value map[string]interface{}) { + m.Cmdy(ice.MDB_EXPORT, ice.WEB_FAVOR, kit.Keys(kit.MDB_HASH, key), kit.MDB_LIST, favor) + }) + } + case "delete", "删除": + m.Richs(ice.WEB_FAVOR, nil, favor, func(key string, value map[string]interface{}) { + m.Cmdy(ice.MDB_DELETE, ice.WEB_FAVOR, kit.Keys(kit.MDB_HASH, key), kit.MDB_DICT) + }) + case "import", "导入": + if favor == "" { + m.Cmdy(ice.MDB_IMPORT, ice.WEB_FAVOR, kit.MDB_HASH, kit.MDB_HASH, "favor") + } else { + m.Richs(ice.WEB_FAVOR, nil, favor, func(key string, value map[string]interface{}) { + m.Cmdy(ice.MDB_IMPORT, ice.WEB_FAVOR, kit.Keys(kit.MDB_HASH, key), kit.MDB_LIST, favor) + }) + } + } + return + } + + if len(arg) == 0 { + // 收藏门类 + m.Richs(ice.WEB_FAVOR, nil, "*", func(key string, value map[string]interface{}) { + m.Push(key, value["meta"], []string{"time", "count"}) + m.Push("render", kit.Select("spide", kit.Value(value, "meta.render"))) + m.Push("favor", kit.Value(value, "meta.name")) + }) + m.Sort("favor") + return + } + + switch arg[0] { + case "save": + f, p, e := kit.Create(arg[1]) + m.Assert(e) + defer f.Close() + w := csv.NewWriter(f) + + w.Write([]string{"favor", "type", "name", "text", "extra"}) + + n := 0 + m.Option("cache.offend", 0) + m.Option("cache.limit", -2) + for _, favor := range arg[2:] { + m.Richs(ice.WEB_FAVOR, nil, favor, func(key string, val map[string]interface{}) { + if m.Conf(ice.WEB_FAVOR, kit.Keys("meta.skip", kit.Value(val, "meta.name"))) == "true" { + return + } + m.Grows(ice.WEB_FAVOR, kit.Keys(kit.MDB_HASH, key), "", "", func(index int, value map[string]interface{}) { + w.Write(kit.Simple(kit.Value(val, "meta.name"), value["type"], value["name"], value["text"], kit.Format(value["extra"]))) + n++ + }) + }) + } + w.Flush() + m.Echo("%s: %d", p, n) + return + + case "load": + f, e := os.Open(arg[1]) + m.Assert(e) + defer f.Close() + r := csv.NewReader(f) + + head, e := r.Read() + m.Assert(e) + m.Info("head: %v", head) + + for { + line, e := r.Read() + if e != nil { + break + } + m.Cmd(ice.WEB_FAVOR, line) + } + return + + case "sync": + m.Richs(ice.WEB_FAVOR, nil, arg[1], func(key string, val map[string]interface{}) { + remote := kit.Keys("meta.remote", arg[2], arg[3]) + count := kit.Int(kit.Value(val, kit.Keys("meta.count"))) + + pull := kit.Int(kit.Value(val, kit.Keys(remote, "pull"))) + m.Cmd(ice.WEB_SPIDE, arg[2], "msg", "/favor/pull", "favor", arg[3], "begin", pull+1).Table(func(index int, value map[string]string, head []string) { + m.Cmd(ice.WEB_FAVOR, arg[1], value["type"], value["name"], value["text"], value["extra"]) + pull = kit.Int(value["id"]) + }) + + m.Option("cache.limit", count-kit.Int(kit.Value(val, kit.Keys(remote, "push")))) + m.Grows(ice.WEB_FAVOR, kit.Keys(kit.MDB_HASH, key), "", "", func(index int, value map[string]interface{}) { + m.Cmd(ice.WEB_SPIDE, arg[2], "msg", "/favor/push", "favor", arg[3], + "type", value["type"], "name", value["name"], "text", value["text"], + "extra", kit.Format(value["extra"]), + ) + pull++ + }) + kit.Value(val, kit.Keys(remote, "pull"), pull) + kit.Value(val, kit.Keys(remote, "push"), kit.Value(val, "meta.count")) + m.Echo("%d", kit.Value(val, "meta.count")) + return + }) + return + } + + m.Option("favor", arg[0]) + fields := []string{kit.MDB_TIME, kit.MDB_ID, kit.MDB_TYPE, kit.MDB_NAME, kit.MDB_TEXT} + if len(arg) > 1 && arg[1] == "extra" { + fields, arg = append(fields, arg[2:]...), arg[:1] + } + if len(arg) < 3 { + m.Richs(ice.WEB_FAVOR, nil, arg[0], func(key string, value map[string]interface{}) { + if len(arg) < 2 { + // 收藏列表 + m.Grows(ice.WEB_FAVOR, kit.Keys(kit.MDB_HASH, key), "", "", func(index int, value map[string]interface{}) { + m.Push("", value, fields) + }) + return + } + // 收藏详情 + m.Grows(ice.WEB_FAVOR, kit.Keys(kit.MDB_HASH, key), "id", arg[1], func(index int, value map[string]interface{}) { + m.Push("detail", value) + m.Optionv("value", value) + m.Push("key", "render") + m.Push("value", m.Cmdx(m.Conf(ice.WEB_FAVOR, kit.Keys("meta.render", value["type"])))) + }) + }) + return + } + + favor := "" + if m.Richs(ice.WEB_FAVOR, nil, arg[0], func(key string, value map[string]interface{}) { + favor = key + }) == nil { + // 创建收藏 + favor = m.Rich(ice.WEB_FAVOR, nil, kit.Data(kit.MDB_NAME, arg[0])) + m.Log(ice.LOG_CREATE, "favor: %s name: %s", favor, arg[0]) + } + + if len(arg) == 3 { + arg = append(arg, "") + } + + // 添加收藏 + index := m.Grow(ice.WEB_FAVOR, kit.Keys(kit.MDB_HASH, favor), kit.Dict( + kit.MDB_TYPE, arg[1], kit.MDB_NAME, arg[2], kit.MDB_TEXT, arg[3], + "extra", kit.Dict(arg[4:]), + )) + m.Richs(ice.WEB_FAVOR, nil, favor, func(key string, value map[string]interface{}) { + kit.Value(value, "meta.time", m.Time()) + }) + m.Log(ice.LOG_INSERT, "favor: %s index: %d name: %s text: %s", arg[0], index, arg[2], arg[3]) + m.Echo("%d", index) + + // 分发数据 + if p := kit.Select(m.Conf(ice.WEB_FAVOR, "meta.proxy"), m.Option("you")); p != "" { + m.Option("you", "") + m.Cmdy(ice.WEB_PROXY, p, ice.WEB_FAVOR, arg) + } + }}, + "/favor/": {Name: "/story/", Help: "收藏夹", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + + switch arg[0] { + case "pull": + m.Richs(ice.WEB_FAVOR, nil, m.Option("favor"), func(key string, value map[string]interface{}) { + m.Option("cache.limit", kit.Int(kit.Value(value, "meta.count"))+1-kit.Int(m.Option("begin"))) + m.Grows(ice.WEB_FAVOR, kit.Keys(kit.MDB_HASH, key), "", "", func(index int, value map[string]interface{}) { + m.Log(ice.LOG_EXPORT, "%v", value) + m.Push("", value, []string{"id", "type", "name", "text"}) + m.Push("extra", kit.Format(value["extra"])) + }) + }) + case "push": + m.Cmdy(ice.WEB_FAVOR, m.Option("favor"), m.Option("type"), m.Option("name"), m.Option("text"), m.Option("extra")) + } + }}, + }}, nil) +} diff --git a/base/web/group.go b/base/web/group.go new file mode 100644 index 00000000..b0601d38 --- /dev/null +++ b/base/web/group.go @@ -0,0 +1,156 @@ +package web + +import ( + ice "github.com/shylinux/icebergs" + kit "github.com/shylinux/toolkits" +) + +func init() { + Index.Merge(&ice.Context{ + Configs: map[string]*ice.Config{ + ice.WEB_GROUP: {Name: "group", Help: "分组", Value: kit.Data(kit.MDB_SHORT, "group")}, + }, + Commands: map[string]*ice.Command{ + ice.WEB_GROUP: {Name: "group group=auto name=auto auto", Help: "分组", Meta: kit.Dict( + "exports", []string{"grp", "group"}, "detail", []string{"标签", "添加", "退还"}, + ), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + if len(arg) > 1 && arg[0] == "action" { + switch arg[1] { + case "label", "标签": + if m.Option(ice.EXPORT_LABEL) != "" && m.Option(cmd) != "" { + m.Cmdy(ice.WEB_LABEL, m.Option(ice.EXPORT_LABEL), "add", m.Option(cmd), m.Option(kit.MDB_NAME)) + m.Option(ice.FIELD_RELOAD, "true") + } + case "add", "添加": + if m.Option(cmd) != "" && m.Option(kit.MDB_NAME) != "" { + m.Cmdy(cmd, m.Option(cmd), "add", m.Option(kit.MDB_NAME)) + m.Option(ice.FIELD_RELOAD, "true") + } + case "del", "退还": + if m.Option(cmd) != "" && m.Option(kit.MDB_NAME) != "" { + m.Cmdy(cmd, m.Option(cmd), "del", m.Option(kit.MDB_NAME)) + m.Option(ice.FIELD_RELOAD, "true") + } + case "prune", "清理": + m.Richs(cmd, nil, m.Option(cmd), func(key string, value map[string]interface{}) { + m.Richs(cmd, kit.Keys(kit.MDB_HASH, key), kit.MDB_FOREACH, func(sub string, value map[string]interface{}) { + if value[kit.MDB_STATUS] != "busy" { + m.Cmdy(cmd, m.Option(cmd), "del", value[kit.MDB_NAME]) + m.Option(ice.FIELD_RELOAD, "true") + } + }) + }) + case "clear", "清空": + m.Richs(cmd, nil, m.Option(cmd), func(key string, value map[string]interface{}) { + m.Richs(cmd, kit.Keys(kit.MDB_HASH, key), kit.MDB_FOREACH, func(sub string, value map[string]interface{}) { + if value[kit.MDB_STATUS] == "void" { + last := m.Conf(cmd, kit.Keys(kit.MDB_HASH, key, kit.MDB_HASH, sub)) + m.Logs(ice.LOG_DELETE, cmd, m.Option(cmd), kit.MDB_NAME, value[kit.MDB_NAME], kit.MDB_VALUE, last) + m.Conf(cmd, kit.Keys(kit.MDB_HASH, key, kit.MDB_HASH, sub), "") + m.Option(ice.FIELD_RELOAD, "true") + m.Echo(last) + } + }) + }) + case "delete", "删除": + m.Richs(cmd, nil, m.Option(cmd), func(key string, value map[string]interface{}) { + m.Echo(m.Conf(cmd, kit.Keys(kit.MDB_HASH, key))) + m.Logs(ice.LOG_REMOVE, cmd, m.Option(cmd), kit.MDB_VALUE, m.Conf(cmd, kit.Keys(kit.MDB_HASH, key))) + m.Conf(cmd, kit.Keys(kit.MDB_HASH, key), "") + m.Option(ice.FIELD_RELOAD, "true") + }) + } + return + } + + if len(arg) < 3 { + m.Richs(cmd, nil, kit.Select(kit.MDB_FOREACH, arg, 0), func(key string, value map[string]interface{}) { + if len(arg) < 1 { + // 一级列表 + m.Option(ice.FIELD_DETAIL, "清理", "清空", "删除") + value = value[kit.MDB_META].(map[string]interface{}) + m.Push(key, value, []string{kit.MDB_TIME}) + status := map[string]int{} + m.Richs(cmd, kit.Keys(kit.MDB_HASH, key), kit.MDB_FOREACH, func(key string, value map[string]interface{}) { + status[kit.Format(value[kit.MDB_STATUS])]++ + }) + m.Push("count", kit.Format("%d/%d/%d", status["busy"], status["free"], status["void"])) + m.Push(key, value, []string{cmd}) + return + } + m.Richs(cmd, kit.Keys(kit.MDB_HASH, key), kit.Select("*", arg, 1), func(key string, value map[string]interface{}) { + if len(arg) < 2 { + // 二级列表 + m.Option(ice.FIELD_DETAIL, "标签", "添加", "退还", "清理", "清空") + m.Push(key, value, []string{kit.MDB_TIME, kit.MDB_STATUS, kit.MDB_NAME}) + return + } + // 分组详情 + m.Option(ice.FIELD_DETAIL, "标签", "添加", "退还") + m.Push("detail", value) + }) + }) + if len(arg) < 1 { + m.Sort(cmd) + } else if len(arg) < 2 { + m.Sort(kit.MDB_NAME) + } + return + } + + if m.Richs(cmd, nil, arg[0], nil) == nil { + // 添加分组 + m.Logs(ice.LOG_CREATE, cmd, m.Rich(cmd, nil, kit.Data( + kit.MDB_SHORT, kit.MDB_NAME, cmd, arg[0], + ))) + } + + m.Richs(cmd, nil, arg[0], func(key string, value map[string]interface{}) { + switch arg[1] { + case "add": // 添加设备 + if m.Richs(cmd, kit.Keys(kit.MDB_HASH, key), arg[2], func(key string, value map[string]interface{}) { + if value[kit.MDB_STATUS] == "void" { + value[kit.MDB_STATUS] = "free" + m.Logs(ice.LOG_MODIFY, cmd, arg[0], kit.MDB_NAME, arg[2], kit.MDB_STATUS, value[kit.MDB_STATUS]) + } + }) == nil { + m.Logs(ice.LOG_INSERT, cmd, arg[0], kit.MDB_NAME, arg[2]) + m.Rich(cmd, kit.Keys(kit.MDB_HASH, key), kit.Dict( + kit.MDB_NAME, arg[2], kit.MDB_STATUS, "free", + )) + } + m.Echo(arg[0]) + case "del": // 删除设备 + m.Richs(cmd, kit.Keys(kit.MDB_HASH, key), arg[2], func(sub string, value map[string]interface{}) { + if value[kit.MDB_STATUS] == "free" { + value[kit.MDB_STATUS] = "void" + m.Logs(ice.LOG_MODIFY, cmd, arg[0], kit.MDB_NAME, arg[2], kit.MDB_STATUS, value[kit.MDB_STATUS]) + m.Echo(arg[2]) + } + }) + case "get": // 分配设备 + m.Richs(cmd, kit.Keys(kit.MDB_HASH, key), kit.Select("%", arg, 2), func(sub string, value map[string]interface{}) { + if value[kit.MDB_STATUS] == "free" { + value[kit.MDB_STATUS] = "busy" + m.Logs(ice.LOG_MODIFY, cmd, arg[0], kit.MDB_NAME, arg[2], kit.MDB_STATUS, value[kit.MDB_STATUS]) + m.Echo("%s", value[kit.MDB_NAME]) + } + }) + case "put": // 回收设备 + m.Richs(cmd, kit.Keys(kit.MDB_HASH, key), arg[2], func(sub string, value map[string]interface{}) { + if value[kit.MDB_STATUS] == "busy" { + value[kit.MDB_STATUS] = "free" + m.Logs(ice.LOG_MODIFY, cmd, arg[0], kit.MDB_NAME, arg[2], kit.MDB_STATUS, value[kit.MDB_STATUS]) + m.Echo("%s", value[kit.MDB_NAME]) + } + }) + default: + m.Richs(cmd, kit.Keys(kit.MDB_HASH, key), arg[1], func(key string, value map[string]interface{}) { + // 执行命令 + m.Cmdy(ice.WEB_PROXY, value[kit.MDB_NAME], arg[2:]) + }) + } + }) + }}, + }}, nil) +} diff --git a/base/web/proxy.go b/base/web/proxy.go new file mode 100644 index 00000000..28ea2323 --- /dev/null +++ b/base/web/proxy.go @@ -0,0 +1,35 @@ +package web + +import ( + ice "github.com/shylinux/icebergs" + kit "github.com/shylinux/toolkits" +) + +func init() { + Index.Merge(&ice.Context{ + Configs: map[string]*ice.Config{ + ice.WEB_PROXY: {Name: "proxy", Help: "代理", Value: kit.Data(kit.MDB_SHORT, "proxy")}, + }, + Commands: map[string]*ice.Command{ + ice.WEB_PROXY: {Name: "proxy name cmd auto", Help: "代理", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + switch arg[0] { + case "add": + m.Rich(ice.WEB_SPACE, nil, kit.Dict( + kit.MDB_TYPE, ice.WEB_BETTER, kit.MDB_NAME, arg[1], kit.MDB_TEXT, arg[2], + )) + m.Conf(ice.WEB_PROXY, kit.Keys("meta.better", arg[1]), arg[2]) + m.Logs(ice.LOG_INSERT, "proxy", arg[1], "cb", arg[2]) + return + } + + m.Richs(ice.WEB_SPACE, nil, arg[0], func(key string, value map[string]interface{}) { + if value[kit.MDB_TYPE] == ice.WEB_BETTER { + arg[0] = m.Cmdx(m.Conf(ice.WEB_PROXY, kit.Keys("meta.better", arg[0]))) + m.Logs(ice.LOG_SELECT, "proxy", value["name"], "space", arg[0]) + } + }) + + m.Cmdy(ice.WEB_ROUTE, arg[0], arg[1:]) + }}, + }}, nil) +} diff --git a/base/web/route.go b/base/web/route.go index cb09c9c2..35a9100f 100644 --- a/base/web/route.go +++ b/base/web/route.go @@ -1,8 +1,8 @@ package web import ( - "github.com/shylinux/icebergs" - "github.com/shylinux/toolkits" + ice "github.com/shylinux/icebergs" + kit "github.com/shylinux/toolkits" "strings" ) @@ -34,6 +34,10 @@ func init() { } return } + if arg[0] == "" { + m.Cmdy(arg[1:]) + return + } target, rest := _route_split(arg...) m.Richs(ice.WEB_SPACE, nil, target, func(key string, val map[string]interface{}) { diff --git a/base/web/share.go b/base/web/share.go index ebf4ed58..f87126b9 100644 --- a/base/web/share.go +++ b/base/web/share.go @@ -1,8 +1,10 @@ package web import ( - "github.com/shylinux/icebergs" - "github.com/shylinux/toolkits" + "os" + + ice "github.com/shylinux/icebergs" + kit "github.com/shylinux/toolkits" "fmt" "path" @@ -215,5 +217,35 @@ 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:]...))) + }}, + "/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) + return + } + + p := path.Join(kit.Simple(m.Conf(ice.WEB_SERVE, "meta.publish"), arg)...) + if m.W == nil { + 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) + } + }}, }}, nil) } diff --git a/base/web/story.go b/base/web/story.go index 68ccdd7f..850bc973 100644 --- a/base/web/story.go +++ b/base/web/story.go @@ -1,8 +1,8 @@ package web import ( - "github.com/shylinux/icebergs" - "github.com/shylinux/toolkits" + ice "github.com/shylinux/icebergs" + kit "github.com/shylinux/toolkits" "os" "path" @@ -382,5 +382,68 @@ func init() { }) } }}, + "/story/": {Name: "/story/", Help: "故事会", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + + switch arg[0] { + case ice.STORY_PULL: + // 下载节点 + + list := m.Cmd(ice.WEB_STORY, ice.STORY_INDEX, m.Option("begin")).Append("list") + for i := 0; i < 10 && list != "" && list != m.Option("end"); i++ { + if m.Richs(ice.WEB_STORY, nil, list, func(key string, value map[string]interface{}) { + // 节点信息 + m.Push("list", key) + m.Push("node", kit.Format(value)) + m.Push("data", value["data"]) + m.Push("save", kit.Format(m.Richs(ice.WEB_CACHE, nil, value["data"], nil))) + list = kit.Format(value["prev"]) + }) == nil { + break + } + } + m.Log(ice.LOG_EXPORT, "%s %s", m.Option("begin"), m.Format("append")) + + case ice.STORY_PUSH: + // 上传节点 + + if m.Richs(ice.WEB_CACHE, nil, m.Option("data"), nil) == nil { + // 导入缓存 + m.Log(ice.LOG_IMPORT, "%v: %v", m.Option("data"), m.Option("save")) + m.Conf(ice.WEB_CACHE, kit.Keys("hash", m.Option("data")), kit.UnMarshal(m.Option("save"))) + } + + node := kit.UnMarshal(m.Option("node")).(map[string]interface{}) + if m.Richs(ice.WEB_STORY, nil, m.Option("list"), nil) == nil { + // 导入节点 + m.Log(ice.LOG_IMPORT, "%v: %v", m.Option("list"), m.Option("node")) + m.Conf(ice.WEB_STORY, kit.Keys("hash", m.Option("list")), node) + } + + if head := m.Richs(ice.WEB_STORY, "head", m.Option("story"), nil); head == nil { + // 自动创建 + h := m.Rich(ice.WEB_STORY, "head", kit.Dict( + "scene", node["scene"], "story", m.Option("story"), + "count", node["count"], "list", m.Option("list"), + )) + m.Log(ice.LOG_CREATE, "%v: %v", h, m.Option("story")) + } else if head["list"] == kit.Format(node["prev"]) || head["list"] == kit.Format(node["pull"]) { + // 快速合并 + head["list"] = m.Option("list") + head["count"] = node["count"] + head["time"] = node["time"] + } else { + // 推送失败 + } + + case ice.STORY_UPLOAD: + // 上传数据 + m.Cmdy(ice.WEB_CACHE, "upload") + + case ice.STORY_DOWNLOAD: + // 下载数据 + m.Cmdy(ice.WEB_STORY, ice.STORY_INDEX, arg[1]) + m.Render(kit.Select(ice.RENDER_DOWNLOAD, ice.RENDER_RESULT, m.Append("file") == ""), m.Append("text")) + } + }}, }}, nil) } diff --git a/base/web/web.go b/base/web/web.go index b37e122e..30ebb81a 100644 --- a/base/web/web.go +++ b/base/web/web.go @@ -7,7 +7,6 @@ import ( "github.com/skip2/go-qrcode" "bytes" - "encoding/csv" "encoding/json" "fmt" "io" @@ -478,17 +477,6 @@ var Index = &ice.Context{Name: "web", Help: "网络模块", // "cmd", []interface{}{ice.CLI_SYSTEM, "ice.sh", "start", ice.WEB_SPACE, "connect"}, "cmd", []interface{}{ice.CLI_SYSTEM, "ice.bin", ice.WEB_SPACE, "connect"}, )}, - - ice.WEB_FAVOR: {Name: "favor", Help: "收藏夹", Value: kit.Data( - kit.MDB_SHORT, kit.MDB_NAME, "template", favor_template, - "proxy", "", - )}, - ice.WEB_CACHE: {Name: "cache", Help: "缓存池", Value: kit.Data( - kit.MDB_SHORT, "text", "path", "var/file", "store", "var/data", "fsize", "100000", "limit", "50", "least", "30", - )}, - - ice.WEB_PROXY: {Name: "proxy", Help: "代理", Value: kit.Data(kit.MDB_SHORT, "proxy")}, - ice.WEB_GROUP: {Name: "group", Help: "分组", Value: kit.Data(kit.MDB_SHORT, "group")}, }, Commands: map[string]*ice.Command{ ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { @@ -1037,491 +1025,6 @@ var Index = &ice.Context{Name: "web", Help: "网络模块", m.Cmdy("nfs.dir", p) }}, - ice.WEB_FAVOR: {Name: "favor favor=auto id=auto auto", Help: "收藏夹", Meta: kit.Dict( - "exports", []string{"hot", "favor"}, "detail", []string{"编辑", "收藏", "收录", "导出", "删除"}, - ), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - if len(arg) > 1 && arg[0] == "action" { - favor, id := m.Option("favor"), m.Option("id") - switch arg[2] { - case "favor": - favor = arg[3] - case "id": - id = arg[3] - } - - switch arg[1] { - case "modify", "编辑": - m.Richs(ice.WEB_FAVOR, nil, favor, func(key string, value map[string]interface{}) { - if id == "" { - m.Log(ice.LOG_MODIFY, "favor: %s value: %v->%v", key, kit.Value(value, kit.Keys("meta", arg[2])), arg[3]) - m.Echo("%s->%s", kit.Value(value, kit.Keys("meta", arg[2])), arg[3]) - kit.Value(value, kit.Keys("meta", arg[2]), arg[3]) - return - } - m.Grows(ice.WEB_FAVOR, kit.Keys(kit.MDB_HASH, key), "id", id, func(index int, value map[string]interface{}) { - m.Log(ice.LOG_MODIFY, "favor: %s index: %d value: %v->%v", key, index, value[arg[2]], arg[3]) - m.Echo("%s->%s", value[arg[2]], arg[3]) - kit.Value(value, arg[2], arg[3]) - }) - }) - case "commit", "收录": - m.Echo("list: ") - m.Richs(ice.WEB_FAVOR, nil, favor, func(key string, value map[string]interface{}) { - m.Grows(ice.WEB_FAVOR, kit.Keys(kit.MDB_HASH, key), "id", id, func(index int, value map[string]interface{}) { - m.Cmdy(ice.WEB_STORY, "add", value["type"], value["name"], value["text"]) - }) - }) - case "export", "导出": - m.Echo("list: ") - if favor == "" { - m.Cmdy(ice.MDB_EXPORT, ice.WEB_FAVOR, kit.MDB_HASH, kit.MDB_HASH, "favor") - } else { - m.Richs(ice.WEB_FAVOR, nil, favor, func(key string, value map[string]interface{}) { - m.Cmdy(ice.MDB_EXPORT, ice.WEB_FAVOR, kit.Keys(kit.MDB_HASH, key), kit.MDB_LIST, favor) - }) - } - case "delete", "删除": - m.Richs(ice.WEB_FAVOR, nil, favor, func(key string, value map[string]interface{}) { - m.Cmdy(ice.MDB_DELETE, ice.WEB_FAVOR, kit.Keys(kit.MDB_HASH, key), kit.MDB_DICT) - }) - case "import", "导入": - if favor == "" { - m.Cmdy(ice.MDB_IMPORT, ice.WEB_FAVOR, kit.MDB_HASH, kit.MDB_HASH, "favor") - } else { - m.Richs(ice.WEB_FAVOR, nil, favor, func(key string, value map[string]interface{}) { - m.Cmdy(ice.MDB_IMPORT, ice.WEB_FAVOR, kit.Keys(kit.MDB_HASH, key), kit.MDB_LIST, favor) - }) - } - } - return - } - - if len(arg) == 0 { - // 收藏门类 - m.Richs(ice.WEB_FAVOR, nil, "*", func(key string, value map[string]interface{}) { - m.Push(key, value["meta"], []string{"time", "count"}) - m.Push("render", kit.Select("spide", kit.Value(value, "meta.render"))) - m.Push("favor", kit.Value(value, "meta.name")) - }) - m.Sort("favor") - return - } - - switch arg[0] { - case "save": - f, p, e := kit.Create(arg[1]) - m.Assert(e) - defer f.Close() - w := csv.NewWriter(f) - - w.Write([]string{"favor", "type", "name", "text", "extra"}) - - n := 0 - m.Option("cache.offend", 0) - m.Option("cache.limit", -2) - for _, favor := range arg[2:] { - m.Richs(ice.WEB_FAVOR, nil, favor, func(key string, val map[string]interface{}) { - if m.Conf(ice.WEB_FAVOR, kit.Keys("meta.skip", kit.Value(val, "meta.name"))) == "true" { - return - } - m.Grows(ice.WEB_FAVOR, kit.Keys(kit.MDB_HASH, key), "", "", func(index int, value map[string]interface{}) { - w.Write(kit.Simple(kit.Value(val, "meta.name"), value["type"], value["name"], value["text"], kit.Format(value["extra"]))) - n++ - }) - }) - } - w.Flush() - m.Echo("%s: %d", p, n) - return - - case "load": - f, e := os.Open(arg[1]) - m.Assert(e) - defer f.Close() - r := csv.NewReader(f) - - head, e := r.Read() - m.Assert(e) - m.Info("head: %v", head) - - for { - line, e := r.Read() - if e != nil { - break - } - m.Cmd(ice.WEB_FAVOR, line) - } - return - - case "sync": - m.Richs(ice.WEB_FAVOR, nil, arg[1], func(key string, val map[string]interface{}) { - remote := kit.Keys("meta.remote", arg[2], arg[3]) - count := kit.Int(kit.Value(val, kit.Keys("meta.count"))) - - pull := kit.Int(kit.Value(val, kit.Keys(remote, "pull"))) - m.Cmd(ice.WEB_SPIDE, arg[2], "msg", "/favor/pull", "favor", arg[3], "begin", pull+1).Table(func(index int, value map[string]string, head []string) { - m.Cmd(ice.WEB_FAVOR, arg[1], value["type"], value["name"], value["text"], value["extra"]) - pull = kit.Int(value["id"]) - }) - - m.Option("cache.limit", count-kit.Int(kit.Value(val, kit.Keys(remote, "push")))) - m.Grows(ice.WEB_FAVOR, kit.Keys(kit.MDB_HASH, key), "", "", func(index int, value map[string]interface{}) { - m.Cmd(ice.WEB_SPIDE, arg[2], "msg", "/favor/push", "favor", arg[3], - "type", value["type"], "name", value["name"], "text", value["text"], - "extra", kit.Format(value["extra"]), - ) - pull++ - }) - kit.Value(val, kit.Keys(remote, "pull"), pull) - kit.Value(val, kit.Keys(remote, "push"), kit.Value(val, "meta.count")) - m.Echo("%d", kit.Value(val, "meta.count")) - return - }) - return - } - - m.Option("favor", arg[0]) - fields := []string{kit.MDB_TIME, kit.MDB_ID, kit.MDB_TYPE, kit.MDB_NAME, kit.MDB_TEXT} - if len(arg) > 1 && arg[1] == "extra" { - fields, arg = append(fields, arg[2:]...), arg[:1] - } - if len(arg) < 3 { - m.Richs(ice.WEB_FAVOR, nil, arg[0], func(key string, value map[string]interface{}) { - if len(arg) < 2 { - // 收藏列表 - m.Grows(ice.WEB_FAVOR, kit.Keys(kit.MDB_HASH, key), "", "", func(index int, value map[string]interface{}) { - m.Push("", value, fields) - }) - return - } - // 收藏详情 - m.Grows(ice.WEB_FAVOR, kit.Keys(kit.MDB_HASH, key), "id", arg[1], func(index int, value map[string]interface{}) { - m.Push("detail", value) - m.Optionv("value", value) - m.Push("key", "render") - m.Push("value", m.Cmdx(m.Conf(ice.WEB_FAVOR, kit.Keys("meta.render", value["type"])))) - }) - }) - return - } - - favor := "" - if m.Richs(ice.WEB_FAVOR, nil, arg[0], func(key string, value map[string]interface{}) { - favor = key - }) == nil { - // 创建收藏 - favor = m.Rich(ice.WEB_FAVOR, nil, kit.Data(kit.MDB_NAME, arg[0])) - m.Log(ice.LOG_CREATE, "favor: %s name: %s", favor, arg[0]) - } - - if len(arg) == 3 { - arg = append(arg, "") - } - - // 添加收藏 - index := m.Grow(ice.WEB_FAVOR, kit.Keys(kit.MDB_HASH, favor), kit.Dict( - kit.MDB_TYPE, arg[1], kit.MDB_NAME, arg[2], kit.MDB_TEXT, arg[3], - "extra", kit.Dict(arg[4:]), - )) - m.Richs(ice.WEB_FAVOR, nil, favor, func(key string, value map[string]interface{}) { - kit.Value(value, "meta.time", m.Time()) - }) - m.Log(ice.LOG_INSERT, "favor: %s index: %d name: %s text: %s", arg[0], index, arg[2], arg[3]) - m.Echo("%d", index) - - // 分发数据 - if p := kit.Select(m.Conf(ice.WEB_FAVOR, "meta.proxy"), m.Option("you")); p != "" { - m.Option("you", "") - m.Cmdy(ice.WEB_PROXY, p, ice.WEB_FAVOR, arg) - } - }}, - ice.WEB_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) - }) - 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) - } - } - } - 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) - } - } - } - } 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) - } - } - } - } - 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) - 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]) - } - }}, - - ice.WEB_PROXY: {Name: "proxy name cmd auto", Help: "代理", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - switch arg[0] { - case "add": - m.Rich(ice.WEB_SPACE, nil, kit.Dict( - kit.MDB_TYPE, ice.WEB_BETTER, kit.MDB_NAME, arg[1], kit.MDB_TEXT, arg[2], - )) - m.Conf(ice.WEB_PROXY, kit.Keys("meta.better", arg[1]), arg[2]) - m.Logs(ice.LOG_INSERT, "proxy", arg[1], "cb", arg[2]) - return - } - - m.Richs(ice.WEB_SPACE, nil, arg[0], func(key string, value map[string]interface{}) { - if value[kit.MDB_TYPE] == ice.WEB_BETTER { - arg[0] = m.Cmdx(m.Conf(ice.WEB_PROXY, kit.Keys("meta.better", arg[0]))) - m.Logs(ice.LOG_SELECT, "proxy", value["name"], "space", arg[0]) - } - }) - - m.Cmdy(ice.WEB_ROUTE, arg[0], arg[1:]) - }}, - ice.WEB_GROUP: {Name: "group group=auto name=auto auto", Help: "分组", Meta: kit.Dict( - "exports", []string{"grp", "group"}, "detail", []string{"标签", "添加", "退还"}, - ), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - if len(arg) > 1 && arg[0] == "action" { - switch arg[1] { - case "label", "标签": - if m.Option(ice.EXPORT_LABEL) != "" && m.Option(cmd) != "" { - m.Cmdy(ice.WEB_LABEL, m.Option(ice.EXPORT_LABEL), "add", m.Option(cmd), m.Option(kit.MDB_NAME)) - m.Option(ice.FIELD_RELOAD, "true") - } - case "add", "添加": - if m.Option(cmd) != "" && m.Option(kit.MDB_NAME) != "" { - m.Cmdy(cmd, m.Option(cmd), "add", m.Option(kit.MDB_NAME)) - m.Option(ice.FIELD_RELOAD, "true") - } - case "del", "退还": - if m.Option(cmd) != "" && m.Option(kit.MDB_NAME) != "" { - m.Cmdy(cmd, m.Option(cmd), "del", m.Option(kit.MDB_NAME)) - m.Option(ice.FIELD_RELOAD, "true") - } - case "prune", "清理": - m.Richs(cmd, nil, m.Option(cmd), func(key string, value map[string]interface{}) { - m.Richs(cmd, kit.Keys(kit.MDB_HASH, key), kit.MDB_FOREACH, func(sub string, value map[string]interface{}) { - if value[kit.MDB_STATUS] != "busy" { - m.Cmdy(cmd, m.Option(cmd), "del", value[kit.MDB_NAME]) - m.Option(ice.FIELD_RELOAD, "true") - } - }) - }) - case "clear", "清空": - m.Richs(cmd, nil, m.Option(cmd), func(key string, value map[string]interface{}) { - m.Richs(cmd, kit.Keys(kit.MDB_HASH, key), kit.MDB_FOREACH, func(sub string, value map[string]interface{}) { - if value[kit.MDB_STATUS] == "void" { - last := m.Conf(cmd, kit.Keys(kit.MDB_HASH, key, kit.MDB_HASH, sub)) - m.Logs(ice.LOG_DELETE, cmd, m.Option(cmd), kit.MDB_NAME, value[kit.MDB_NAME], kit.MDB_VALUE, last) - m.Conf(cmd, kit.Keys(kit.MDB_HASH, key, kit.MDB_HASH, sub), "") - m.Option(ice.FIELD_RELOAD, "true") - m.Echo(last) - } - }) - }) - case "delete", "删除": - m.Richs(cmd, nil, m.Option(cmd), func(key string, value map[string]interface{}) { - m.Echo(m.Conf(cmd, kit.Keys(kit.MDB_HASH, key))) - m.Logs(ice.LOG_REMOVE, cmd, m.Option(cmd), kit.MDB_VALUE, m.Conf(cmd, kit.Keys(kit.MDB_HASH, key))) - m.Conf(cmd, kit.Keys(kit.MDB_HASH, key), "") - m.Option(ice.FIELD_RELOAD, "true") - }) - } - return - } - - if len(arg) < 3 { - m.Richs(cmd, nil, kit.Select(kit.MDB_FOREACH, arg, 0), func(key string, value map[string]interface{}) { - if len(arg) < 1 { - // 一级列表 - m.Option(ice.FIELD_DETAIL, "清理", "清空", "删除") - value = value[kit.MDB_META].(map[string]interface{}) - m.Push(key, value, []string{kit.MDB_TIME}) - status := map[string]int{} - m.Richs(cmd, kit.Keys(kit.MDB_HASH, key), kit.MDB_FOREACH, func(key string, value map[string]interface{}) { - status[kit.Format(value[kit.MDB_STATUS])]++ - }) - m.Push("count", kit.Format("%d/%d/%d", status["busy"], status["free"], status["void"])) - m.Push(key, value, []string{cmd}) - return - } - m.Richs(cmd, kit.Keys(kit.MDB_HASH, key), kit.Select("*", arg, 1), func(key string, value map[string]interface{}) { - if len(arg) < 2 { - // 二级列表 - m.Option(ice.FIELD_DETAIL, "标签", "添加", "退还", "清理", "清空") - m.Push(key, value, []string{kit.MDB_TIME, kit.MDB_STATUS, kit.MDB_NAME}) - return - } - // 分组详情 - m.Option(ice.FIELD_DETAIL, "标签", "添加", "退还") - m.Push("detail", value) - }) - }) - if len(arg) < 1 { - m.Sort(cmd) - } else if len(arg) < 2 { - m.Sort(kit.MDB_NAME) - } - return - } - - if m.Richs(cmd, nil, arg[0], nil) == nil { - // 添加分组 - m.Logs(ice.LOG_CREATE, cmd, m.Rich(cmd, nil, kit.Data( - kit.MDB_SHORT, kit.MDB_NAME, cmd, arg[0], - ))) - } - - m.Richs(cmd, nil, arg[0], func(key string, value map[string]interface{}) { - switch arg[1] { - case "add": // 添加设备 - if m.Richs(cmd, kit.Keys(kit.MDB_HASH, key), arg[2], func(key string, value map[string]interface{}) { - if value[kit.MDB_STATUS] == "void" { - value[kit.MDB_STATUS] = "free" - m.Logs(ice.LOG_MODIFY, cmd, arg[0], kit.MDB_NAME, arg[2], kit.MDB_STATUS, value[kit.MDB_STATUS]) - } - }) == nil { - m.Logs(ice.LOG_INSERT, cmd, arg[0], kit.MDB_NAME, arg[2]) - m.Rich(cmd, kit.Keys(kit.MDB_HASH, key), kit.Dict( - kit.MDB_NAME, arg[2], kit.MDB_STATUS, "free", - )) - } - m.Echo(arg[0]) - case "del": // 删除设备 - m.Richs(cmd, kit.Keys(kit.MDB_HASH, key), arg[2], func(sub string, value map[string]interface{}) { - if value[kit.MDB_STATUS] == "free" { - value[kit.MDB_STATUS] = "void" - m.Logs(ice.LOG_MODIFY, cmd, arg[0], kit.MDB_NAME, arg[2], kit.MDB_STATUS, value[kit.MDB_STATUS]) - m.Echo(arg[2]) - } - }) - case "get": // 分配设备 - m.Richs(cmd, kit.Keys(kit.MDB_HASH, key), kit.Select("%", arg, 2), func(sub string, value map[string]interface{}) { - if value[kit.MDB_STATUS] == "free" { - value[kit.MDB_STATUS] = "busy" - m.Logs(ice.LOG_MODIFY, cmd, arg[0], kit.MDB_NAME, arg[2], kit.MDB_STATUS, value[kit.MDB_STATUS]) - m.Echo("%s", value[kit.MDB_NAME]) - } - }) - case "put": // 回收设备 - m.Richs(cmd, kit.Keys(kit.MDB_HASH, key), arg[2], func(sub string, value map[string]interface{}) { - if value[kit.MDB_STATUS] == "busy" { - value[kit.MDB_STATUS] = "free" - m.Logs(ice.LOG_MODIFY, cmd, arg[0], kit.MDB_NAME, arg[2], kit.MDB_STATUS, value[kit.MDB_STATUS]) - m.Echo("%s", value[kit.MDB_NAME]) - } - }) - default: - m.Richs(cmd, kit.Keys(kit.MDB_HASH, key), arg[1], func(key string, value map[string]interface{}) { - // 执行命令 - m.Cmdy(ice.WEB_PROXY, value[kit.MDB_NAME], arg[2:]) - }) - } - }) - }}, - "/space/": {Name: "/space/", Help: "空间站", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { if s, e := websocket.Upgrade(m.W, m.R, nil, m.Confi(ice.WEB_SPACE, "meta.buffer.r"), m.Confi(ice.WEB_SPACE, "meta.buffer.w")); m.Assert(e) { m.Option("name", strings.Replace(kit.Select(m.Option(ice.MSG_USERADDR), m.Option("name")), ".", "_", -1)) @@ -1559,122 +1062,6 @@ var Index = &ice.Context{Name: "web", Help: "网络模块", m.Echo(share) } }}, - - "/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.Render(ice.RENDER_DOWNLOAD, value["file"]) - }) - }}, - "/story/": {Name: "/story/", Help: "故事会", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - - switch arg[0] { - case ice.STORY_PULL: - // 下载节点 - - list := m.Cmd(ice.WEB_STORY, ice.STORY_INDEX, m.Option("begin")).Append("list") - for i := 0; i < 10 && list != "" && list != m.Option("end"); i++ { - if m.Richs(ice.WEB_STORY, nil, list, func(key string, value map[string]interface{}) { - // 节点信息 - m.Push("list", key) - m.Push("node", kit.Format(value)) - m.Push("data", value["data"]) - m.Push("save", kit.Format(m.Richs(ice.WEB_CACHE, nil, value["data"], nil))) - list = kit.Format(value["prev"]) - }) == nil { - break - } - } - m.Log(ice.LOG_EXPORT, "%s %s", m.Option("begin"), m.Format("append")) - - case ice.STORY_PUSH: - // 上传节点 - - if m.Richs(ice.WEB_CACHE, nil, m.Option("data"), nil) == nil { - // 导入缓存 - m.Log(ice.LOG_IMPORT, "%v: %v", m.Option("data"), m.Option("save")) - m.Conf(ice.WEB_CACHE, kit.Keys("hash", m.Option("data")), kit.UnMarshal(m.Option("save"))) - } - - node := kit.UnMarshal(m.Option("node")).(map[string]interface{}) - if m.Richs(ice.WEB_STORY, nil, m.Option("list"), nil) == nil { - // 导入节点 - m.Log(ice.LOG_IMPORT, "%v: %v", m.Option("list"), m.Option("node")) - m.Conf(ice.WEB_STORY, kit.Keys("hash", m.Option("list")), node) - } - - if head := m.Richs(ice.WEB_STORY, "head", m.Option("story"), nil); head == nil { - // 自动创建 - h := m.Rich(ice.WEB_STORY, "head", kit.Dict( - "scene", node["scene"], "story", m.Option("story"), - "count", node["count"], "list", m.Option("list"), - )) - m.Log(ice.LOG_CREATE, "%v: %v", h, m.Option("story")) - } else if head["list"] == kit.Format(node["prev"]) || head["list"] == kit.Format(node["pull"]) { - // 快速合并 - head["list"] = m.Option("list") - head["count"] = node["count"] - head["time"] = node["time"] - } else { - // 推送失败 - } - - case ice.STORY_UPLOAD: - // 上传数据 - m.Cmdy(ice.WEB_CACHE, "upload") - - case ice.STORY_DOWNLOAD: - // 下载数据 - m.Cmdy(ice.WEB_STORY, ice.STORY_INDEX, arg[1]) - m.Render(kit.Select(ice.RENDER_DOWNLOAD, ice.RENDER_RESULT, m.Append("file") == ""), m.Append("text")) - } - }}, - "/favor/": {Name: "/story/", Help: "收藏夹", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - - switch arg[0] { - case "pull": - m.Richs(ice.WEB_FAVOR, nil, m.Option("favor"), func(key string, value map[string]interface{}) { - m.Option("cache.limit", kit.Int(kit.Value(value, "meta.count"))+1-kit.Int(m.Option("begin"))) - m.Grows(ice.WEB_FAVOR, kit.Keys(kit.MDB_HASH, key), "", "", func(index int, value map[string]interface{}) { - m.Log(ice.LOG_EXPORT, "%v", value) - m.Push("", value, []string{"id", "type", "name", "text"}) - m.Push("extra", kit.Format(value["extra"])) - }) - }) - case "push": - m.Cmdy(ice.WEB_FAVOR, m.Option("favor"), m.Option("type"), m.Option("name"), m.Option("text"), m.Option("extra")) - } - }}, - - "/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:]...))) - }}, - "/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) - return - } - - p := path.Join(kit.Simple(m.Conf(ice.WEB_SERVE, "meta.publish"), arg)...) - if m.W == nil { - 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) - } - }}, }, } diff --git a/misc/tmux/tmux.go b/misc/tmux/tmux.go index 18bb2dfb..1c9d0a0e 100644 --- a/misc/tmux/tmux.go +++ b/misc/tmux/tmux.go @@ -1,10 +1,10 @@ package tmux import ( - "github.com/shylinux/icebergs" + ice "github.com/shylinux/icebergs" "github.com/shylinux/icebergs/base/web" "github.com/shylinux/icebergs/core/code" - "github.com/shylinux/toolkits" + kit "github.com/shylinux/toolkits" "os" "path" @@ -43,6 +43,10 @@ var Index = &ice.Context{Name: "tmux", Help: "工作台", }, Commands: map[string]*ice.Command{ ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + if m.Cmdy(ice.CLI_SYSTEM, "tmux", "ls"); m.Append("code") != "0" { + return + } + m.Cmd(ice.WEB_PROXY, "add", "tmux", m.AddCmd(&ice.Command{Name: "proxy", Help: "代理", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Cmd("session").Table(func(index int, value map[string]string, head []string) { if value["tag"] == "1" { diff --git a/misc/zsh/zsh.go b/misc/zsh/zsh.go index e3d4c45f..69dba859 100644 --- a/misc/zsh/zsh.go +++ b/misc/zsh/zsh.go @@ -63,6 +63,7 @@ var Index = &ice.Context{Name: "zsh", Help: "命令行", m.Option("you", kit.Select(m.Conf("zsh", "meta.proxy"), value["you"])) }) + m.Option("arg", strings.ReplaceAll(m.Option("arg"), "%20", " ")) m.Logs(ice.LOG_AUTH, "you", m.Option("you"), "url", m.Option(ice.MSG_USERURL), "cmd", m.Optionv("cmds"), "sub", m.Optionv("sub")) m.Option(ice.MSG_OUTPUT, ice.RENDER_RESULT) }},