1
0
forked from x/icebergs
icebergs/base/web/cache.go
2020-07-20 10:26:25 +08:00

189 lines
5.6 KiB
Go

package web
import (
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/nfs"
kit "github.com/shylinux/toolkits"
"io"
"net/http"
"os"
"path"
)
func _cache_name(m *ice.Message, h string) string {
return path.Join(m.Conf(CACHE, "meta.path"), h[:2], h)
}
func _cache_list(m *ice.Message, key string) {
if key == "" {
m.Grows(CACHE, nil, "", "", func(index int, value map[string]interface{}) {
// 缓存列表
m.Push("", value, []string{kit.MDB_TIME, kit.MDB_ID, DATA, kit.MDB_TYPE})
m.Push(kit.MDB_SIZE, kit.FmtSize(kit.Int64(value[kit.MDB_SIZE])))
m.Push("", value, []string{kit.MDB_NAME, kit.MDB_TEXT})
})
m.Sort(kit.MDB_ID, "int_r")
return
}
m.Richs(CACHE, nil, key, func(key string, value map[string]interface{}) {
// 缓存详情
m.Push("detail", value)
})
}
func _cache_save(m *ice.Message, kind, name, text string, arg ...string) { // file size
if len(text) > 512 {
// 存入文件
p := m.Cmdx(nfs.SAVE, _cache_name(m, kit.Hashs(text)), text)
text, arg = p, kit.Simple(p, len(text))
}
// 添加数据
size := kit.Int(kit.Select(kit.Format(len(text)), arg, 1))
file := kit.Select("", arg, 0)
text = kit.Select(file, text)
h := m.Rich(CACHE, nil, kit.Dict(
kit.MDB_TYPE, kind, kit.MDB_NAME, name, kit.MDB_TEXT, text,
kit.MDB_FILE, file, kit.MDB_SIZE, size,
))
m.Log_CREATE(CACHE, h, kit.MDB_TYPE, kind, kit.MDB_NAME, name)
// 添加记录
m.Grow(CACHE, nil, kit.Dict(
kit.MDB_TYPE, kind, kit.MDB_NAME, name, kit.MDB_TEXT, text,
kit.MDB_SIZE, size, DATA, h,
))
// 返回结果
m.Push(kit.MDB_TIME, m.Time())
m.Push(kit.MDB_TYPE, kind)
m.Push(kit.MDB_NAME, name)
m.Push(kit.MDB_TEXT, text)
m.Push(kit.MDB_SIZE, size)
m.Push(kit.MDB_FILE, file)
m.Push(DATA, h)
}
func _cache_watch(m *ice.Message, key, file string) {
m.Richs(CACHE, nil, key, func(key string, value map[string]interface{}) {
if value[kit.MDB_FILE] == nil {
m.Cmdy(nfs.SAVE, file, value[kit.MDB_TEXT])
} else {
m.Cmdy(nfs.LINK, file, value[kit.MDB_FILE])
}
})
}
func _cache_catch(m *ice.Message, name string) (file, size string) {
if f, e := os.Open(name); m.Assert(e) {
defer f.Close()
if s, e := f.Stat(); m.Assert(e) {
return m.Cmdx(nfs.LINK, _cache_name(m, kit.Hashs(f)), name), kit.Format(s.Size())
}
}
return "", "0"
}
func _cache_upload(m *ice.Message, r *http.Request) (kind, name, file, size string) {
if buf, h, e := r.FormFile(UPLOAD); m.Assert(e) {
defer buf.Close()
// 创建文件
if f, p, e := kit.Create(_cache_name(m, kit.Hashs(buf))); m.Assert(e) {
defer f.Close()
// 导入数据
buf.Seek(0, os.SEEK_SET)
if n, e := io.Copy(f, buf); m.Assert(e) {
m.Log_IMPORT(kit.MDB_FILE, p, kit.MDB_SIZE, kit.FmtSize(int64(n)))
return h.Header.Get("Content-Type"), h.Filename, p, kit.Format(n)
}
}
}
return "", "", "", "0"
}
func _cache_download(m *ice.Message, r *http.Response) (file, size string) {
defer r.Body.Close()
total := kit.Int(kit.Select("1", r.Header.Get("Content-Length")))
if f, p, e := kit.Create(path.Join("var/tmp", kit.Hashs("uniq"))); m.Assert(e) {
size, buf := 0, make([]byte, 1024)
for {
if n, _ := r.Body.Read(buf); n > 0 {
f.Write(buf[0:n])
size += n
m.Log_IMPORT(kit.MDB_FILE, p, "per", size*100/total, kit.MDB_SIZE, kit.FmtSize(int64(size)), "total", kit.FmtSize(int64(total)))
} else {
f.Close()
break
}
}
if f, e := os.Open(p); m.Assert(e) {
defer f.Close()
m.Log_IMPORT(kit.MDB_FILE, p, kit.MDB_SIZE, kit.FmtSize(int64(size)))
c := _cache_name(m, kit.Hashs(f))
m.Cmd(nfs.LINK, c, p)
return c, kit.Format(size)
}
}
return "", "0"
}
const (
WATCH = "watch"
CATCH = "catch"
WRITE = "write"
UPLOAD = "upload"
DOWNLOAD = "download"
)
const CACHE = "cache"
func init() {
Index.Merge(&ice.Context{
Configs: map[string]*ice.Config{
CACHE: {Name: "cache", Help: "缓存池", Value: kit.Data(
kit.MDB_SHORT, kit.MDB_TEXT,
kit.MDB_PATH, "var/file",
kit.MDB_STORE, "var/data",
kit.MDB_FSIZE, "200000",
kit.MDB_LIMIT, "50",
kit.MDB_LEAST, "30",
)},
},
Commands: map[string]*ice.Command{
CACHE: {Name: "cache data=auto auto", Help: "缓存池", Action: map[string]*ice.Action{
WATCH: {Name: "watch key file", Help: "查看", Hand: func(m *ice.Message, arg ...string) {
_cache_watch(m, arg[0], arg[1])
}},
WRITE: {Name: "write type name text", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
_cache_save(m, arg[0], arg[1], arg[2])
}},
CATCH: {Name: "catch type name", Help: "捕获", Hand: func(m *ice.Message, arg ...string) {
file, size := _cache_catch(m, arg[1])
_cache_save(m, arg[0], arg[1], "", file, size)
}},
UPLOAD: {Name: "upload", Help: "上传", Hand: func(m *ice.Message, arg ...string) {
kind, name, file, size := _cache_upload(m, m.R)
_cache_save(m, kind, name, "", file, size)
}},
DOWNLOAD: {Name: "download type name", Help: "下载", Hand: func(m *ice.Message, arg ...string) {
if r, ok := m.Optionv("response").(*http.Response); ok {
file, size := _cache_download(m, r)
_cache_save(m, arg[0], arg[1], "", file, size)
}
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
_cache_list(m, kit.Select("", arg, 0))
}},
"/cache/": {Name: "/cache/", Help: "缓存池", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Richs(CACHE, nil, arg[0], func(key string, value map[string]interface{}) {
if value[kit.MDB_FILE] == nil {
m.Render(ice.RENDER_DOWNLOAD, value[kit.MDB_FILE])
} else {
m.Render(ice.RENDER_RESULT, value[kit.MDB_TEXT])
}
})
}},
}}, nil)
}