1
0
forked from x/icebergs
This commit is contained in:
shaoying 2020-05-21 20:53:22 +08:00
parent 41c379a35f
commit d1cd4c5646
10 changed files with 692 additions and 621 deletions

153
base/web/cache.go Normal file
View File

@ -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)
}

236
base/web/favor.go Normal file
View File

@ -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)
}

156
base/web/group.go Normal file
View File

@ -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)
}

35
base/web/proxy.go Normal file
View File

@ -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)
}

View File

@ -1,8 +1,8 @@
package web package web
import ( import (
"github.com/shylinux/icebergs" ice "github.com/shylinux/icebergs"
"github.com/shylinux/toolkits" kit "github.com/shylinux/toolkits"
"strings" "strings"
) )
@ -34,6 +34,10 @@ func init() {
} }
return return
} }
if arg[0] == "" {
m.Cmdy(arg[1:])
return
}
target, rest := _route_split(arg...) target, rest := _route_split(arg...)
m.Richs(ice.WEB_SPACE, nil, target, func(key string, val map[string]interface{}) { m.Richs(ice.WEB_SPACE, nil, target, func(key string, val map[string]interface{}) {

View File

@ -1,8 +1,10 @@
package web package web
import ( import (
"github.com/shylinux/icebergs" "os"
"github.com/shylinux/toolkits"
ice "github.com/shylinux/icebergs"
kit "github.com/shylinux/toolkits"
"fmt" "fmt"
"path" "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) }}, nil)
} }

View File

@ -1,8 +1,8 @@
package web package web
import ( import (
"github.com/shylinux/icebergs" ice "github.com/shylinux/icebergs"
"github.com/shylinux/toolkits" kit "github.com/shylinux/toolkits"
"os" "os"
"path" "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) }}, nil)
} }

View File

@ -7,7 +7,6 @@ import (
"github.com/skip2/go-qrcode" "github.com/skip2/go-qrcode"
"bytes" "bytes"
"encoding/csv"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io" "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.sh", "start", ice.WEB_SPACE, "connect"},
"cmd", []interface{}{ice.CLI_SYSTEM, "ice.bin", 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{ Commands: map[string]*ice.Command{
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { 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) 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) { "/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) { 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)) 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) 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)
}
}},
}, },
} }

View File

@ -1,10 +1,10 @@
package tmux package tmux
import ( import (
"github.com/shylinux/icebergs" ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/web" "github.com/shylinux/icebergs/base/web"
"github.com/shylinux/icebergs/core/code" "github.com/shylinux/icebergs/core/code"
"github.com/shylinux/toolkits" kit "github.com/shylinux/toolkits"
"os" "os"
"path" "path"
@ -43,6 +43,10 @@ var Index = &ice.Context{Name: "tmux", Help: "工作台",
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { 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(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) { m.Cmd("session").Table(func(index int, value map[string]string, head []string) {
if value["tag"] == "1" { if value["tag"] == "1" {

View File

@ -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("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.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) m.Option(ice.MSG_OUTPUT, ice.RENDER_RESULT)
}}, }},