diff --git a/base/aaa/role.go b/base/aaa/role.go
index 34a901a2..3765fb02 100644
--- a/base/aaa/role.go
+++ b/base/aaa/role.go
@@ -133,7 +133,7 @@ func RoleRight(m *ice.Message, role string, key ...string) bool {
}
func Right(m *ice.Message, key ...ice.Any) bool {
return m.Option(ice.MSG_USERROLE) == ROOT || !m.Warn(m.Cmdx(ROLE, RIGHT, m.Option(ice.MSG_USERROLE), key) != ice.OK,
- ice.ErrNotRight, kit.Keys(key...), USERROLE, m.Option(ice.MSG_USERROLE), logs.FileLineMeta(logs.FileLine(2)))
+ ice.ErrNotRight, kit.Keys(key...), USERROLE, m.Option(ice.MSG_USERROLE), logs.FileLineMeta(2))
}
func White(m *ice.Message, key ...string) {
diff --git a/base/aaa/sess.go b/base/aaa/sess.go
index c267489e..2363c7bc 100644
--- a/base/aaa/sess.go
+++ b/base/aaa/sess.go
@@ -67,9 +67,9 @@ func SessCreate(m *ice.Message, username string) string {
return m.Option(ice.MSG_SESSID, m.Cmdx(SESS, mdb.CREATE, username))
}
func SessCheck(m *ice.Message, sessid string) bool {
- m.Option("aaa.checker", logs.FileLine(2))
+ m.Option("aaa.checker", logs.FileLine(-1))
m.Options(ice.MSG_USERNAME, "", ice.MSG_USERNICK, "", ice.MSG_USERROLE, VOID)
- return sessid != "" && m.Cmdy(SESS, CHECK, sessid).Option(ice.MSG_USERNAME) != ""
+ return sessid != "" && m.Cmdy(SESS, CHECK, sessid, logs.FileLineMeta(-1)).Option(ice.MSG_USERNAME) != ""
}
func SessAuth(m *ice.Message, value ice.Any, arg ...string) *ice.Message {
return m.Auth(
diff --git a/base/ctx/command.go b/base/ctx/command.go
index 6aecf779..adaaa900 100644
--- a/base/ctx/command.go
+++ b/base/ctx/command.go
@@ -120,15 +120,16 @@ func Run(m *ice.Message, arg ...string) {
}
}
}
- if !PodCmd(m, arg) && aaa.Right(m, arg) {
+ if Upload(m); !PodCmd(m, arg) && aaa.Right(m, arg) {
m.Cmdy(arg)
}
}
+
+var Upload = func(*ice.Message) {}
+
func PodCmd(m *ice.Message, arg ...ice.Any) bool {
if pod := m.Option(ice.POD); pod != "" {
- if m.Option(ice.POD, ""); len(kit.Simple(m.Optionv(ice.MSG_UPLOAD))) == 1 {
- m.Cmdy("cache", "upload").Option(ice.MSG_UPLOAD, m.Append(mdb.HASH), m.Append(mdb.NAME), m.Append(nfs.SIZE))
- }
+ m.Option(ice.POD, "")
m.Cmdy(append(kit.List(ice.SPACE, pod), arg...)...)
return true
}
diff --git a/base/gdb/event.go b/base/gdb/event.go
index 8fee16b6..1e4f1286 100644
--- a/base/gdb/event.go
+++ b/base/gdb/event.go
@@ -13,11 +13,14 @@ const (
)
const EVENT = "event"
+var list map[string]int = map[string]int{}
+
func init() {
Index.MergeCommands(ice.Commands{
EVENT: {Name: "event event id auto listen happen", Help: "事件流", Actions: ice.MergeActions(ice.Actions{
LISTEN: {Name: "listen event cmd", Help: "监听", Hand: func(m *ice.Message, arg ...string) {
mdb.ZoneInsert(m, m.OptionSimple(EVENT, ice.CMD))
+ list[m.Option(EVENT)]++
}},
HAPPEN: {Name: "happen event", Help: "触发", Hand: func(m *ice.Message, arg ...string) {
defer m.Cost()
@@ -55,7 +58,10 @@ func Watch(m *ice.Message, key string, arg ...string) *ice.Message {
return m.Cmd(EVENT, LISTEN, EVENT, key, ice.CMD, kit.Join(arg, ice.SP))
}
func Event(m *ice.Message, key string, arg ...ice.Any) *ice.Message {
- return m.Cmdy(EVENT, HAPPEN, EVENT, kit.Select(kit.Keys(m.CommandKey(), m.ActionKey()), key), arg, logs.FileLineMeta(logs.FileLine(-1)))
+ if list[key] == 0 {
+ return m
+ }
+ return m.Cmdy(EVENT, HAPPEN, EVENT, kit.Select(kit.Keys(m.CommandKey(), m.ActionKey()), key), arg, logs.FileLineMeta(-1))
}
func EventDeferEvent(m *ice.Message, key string, arg ...ice.Any) func(string, ...ice.Any) {
Event(m, key, arg...)
diff --git a/base/mdb/hash.go b/base/mdb/hash.go
index 4abb589c..fa241b2e 100644
--- a/base/mdb/hash.go
+++ b/base/mdb/hash.go
@@ -169,7 +169,7 @@ func HashCreate(m *ice.Message, arg ...Any) string {
if len(arg) == 0 {
arg = append(arg, m.OptionSimple(HashField(m)))
}
- return m.Echo(m.Cmdx(append(kit.List(INSERT, m.PrefixKey(), "", HASH, logs.FileLineMeta(logs.FileLine(-1))), arg...)...)).Result()
+ return m.Echo(m.Cmdx(append(kit.List(INSERT, m.PrefixKey(), "", HASH, logs.FileLineMeta(-1)), arg...)...)).Result()
}
func HashRemove(m *ice.Message, arg ...Any) *ice.Message {
if args := kit.Simple(arg); len(args) == 0 {
@@ -191,7 +191,7 @@ func HashSelect(m *ice.Message, arg ...string) *ice.Message {
} else {
m.Fields(len(kit.Slice(arg, 0, 1)), HashField(m))
}
- m.Cmdy(SELECT, m.PrefixKey(), "", HASH, HashShort(m), arg)
+ m.Cmdy(SELECT, m.PrefixKey(), "", HASH, HashShort(m), arg, logs.FileLineMeta(-1))
if m.PushAction(m.Config(ACTION), REMOVE); !m.FieldsIsDetail() {
return m.StatusTimeCount()
}
diff --git a/base/mdb/render.go b/base/mdb/render.go
index c56b9307..66cd4880 100644
--- a/base/mdb/render.go
+++ b/base/mdb/render.go
@@ -27,12 +27,13 @@ func RenderAction(args ...ice.Any) ice.Actions {
m.Cmdy(INSERT, m.PrefixKey(), "", HASH, m.OptionSimple(TYPE, NAME, TEXT))
}},
SELECT: {Name: "select type name text auto create", Hand: func(m *ice.Message, arg ...string) {
- if len(arg) < 2 || arg[0] == "" || arg[1] == "" {
+ if len(arg) < 2 || arg[0] == "" {
HashSelect(m, arg...)
return
}
for _, k := range kit.Split(arg[0]) {
HashSelect(m.Spawn(ice.OptionFields("")), k).Tables(func(value ice.Maps) {
+ m.Debug("what %v", m.OptionFields())
m.Cmdy(kit.Keys(value[TEXT], value[NAME]), m.CommandKey(), k, arg[1], kit.Select("", arg, 2), kit.Slice(arg, 3))
})
}
diff --git a/base/mdb/zone.go b/base/mdb/zone.go
index cb48266a..272f41cf 100644
--- a/base/mdb/zone.go
+++ b/base/mdb/zone.go
@@ -73,7 +73,9 @@ func _zone_export(m *ice.Message, prefix, chain, file string) {
defer Lock(m, prefix, chain)()
Grows(m, prefix, chain, "", "", func(value ice.Map) {
value = kit.GetMeta(value)
- w.Write(kit.Simple(head, func(k string) string { return kit.Select(kit.Format(kit.Value(val, k)), kit.Format(kit.Value(value, k))) }))
+ w.Write(kit.Simple(head, func(k string) string {
+ return kit.Select(kit.Format(kit.Value(val, k)), kit.Format(kit.Value(value, k)))
+ }))
count++
})
})
@@ -155,7 +157,9 @@ func ZoneKey(m *ice.Message) string {
}
return ZoneShort(m)
}
-func ZoneShort(m *ice.Message) string { return kit.Select(ZONE, m.Config(SHORT), m.Config(SHORT) != UNIQ) }
+func ZoneShort(m *ice.Message) string {
+ return kit.Select(ZONE, m.Config(SHORT), m.Config(SHORT) != UNIQ)
+}
func ZoneField(m *ice.Message) string { return kit.Select(ZONE_FIELD, m.Config(FIELD)) }
func ZoneInputs(m *ice.Message, arg ...Any) {
m.Cmdy(INPUTS, m.PrefixKey(), "", ZONE, m.Option(ZoneKey(m)), arg)
@@ -188,7 +192,7 @@ func ZoneModify(m *ice.Message, arg ...Any) {
func ZoneSelect(m *ice.Message, arg ...string) *ice.Message {
arg = kit.Slice(arg, 0, 2)
m.Fields(len(arg), kit.Select(kit.Fields(TIME, m.Config(SHORT), COUNT), m.Config(FIELDS)), ZoneField(m))
- if m.Cmdy(SELECT, m.PrefixKey(), "", ZONE, arg, logs.FileLineMeta(logs.FileLine(-1))); len(arg) == 0 {
+ if m.Cmdy(SELECT, m.PrefixKey(), "", ZONE, arg, logs.FileLineMeta(-1)); len(arg) == 0 {
m.Sort(ZoneShort(m)).StatusTimeCount().PushAction(m.Config(ACTION), REMOVE)
} else if len(arg) == 1 {
m.StatusTimeCountTotal(_mdb_getmeta(m, "", kit.Keys(HASH, HashSelectField(m, arg[0], HASH)), COUNT))
diff --git a/base/nfs/dir.go b/base/nfs/dir.go
index ceec201c..98db5370 100644
--- a/base/nfs/dir.go
+++ b/base/nfs/dir.go
@@ -168,8 +168,7 @@ func init() {
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
aaa.White(m, ice.SRC, ice.BIN, ice.USR, ice.USR_PUBLISH, ice.USR_LOCAL_GO)
aaa.Black(m, ice.BIN_BOOT_LOG, ice.USR_LOCAL)
- }},
- mdb.UPLOAD: {Hand: func(m *ice.Message, arg ...string) { m.Cmdy("web.cache", "upload_watch", m.Option(PATH)) }},
+ }}, mdb.UPLOAD: {},
TRASH: {Hand: func(m *ice.Message, arg ...string) { m.Cmd(TRASH, mdb.CREATE, m.Option(PATH)) }},
}, Hand: func(m *ice.Message, arg ...string) {
root, dir := kit.Select(PWD, m.Option(DIR_ROOT)), kit.Select(PWD, arg, 0)
diff --git a/base/nfs/pack.go b/base/nfs/pack.go
index 0db271e1..307b44db 100644
--- a/base/nfs/pack.go
+++ b/base/nfs/pack.go
@@ -150,8 +150,8 @@ func CloseFile(m *ice.Message, p ice.Any) {
}
}
-func CopyFile(m *ice.Message, to io.WriteCloser, from io.ReadCloser, total int, cb ice.Any) {
- size, buf := 0, make([]byte, ice.MOD_BUFS)
+func CopyFile(m *ice.Message, to io.WriteCloser, from io.ReadCloser, bufs, total int, cb ice.Any) {
+ size, buf := 0, make([]byte, bufs)
for {
n, e := from.Read(buf)
to.Write(buf[0:n])
@@ -167,7 +167,7 @@ func CopyFile(m *ice.Message, to io.WriteCloser, from io.ReadCloser, total int,
default:
m.ErrorNotImplement(cb)
}
- if m.Warn(e) {
+ if e == io.EOF || m.Warn(e) {
break
}
}
diff --git a/base/web/cache.go b/base/web/cache.go
index fe6dfc97..eeefb04f 100644
--- a/base/web/cache.go
+++ b/base/web/cache.go
@@ -1,67 +1,62 @@
package web
import (
+ "fmt"
"io"
"net/http"
"os"
"path"
+ "strings"
ice "shylinux.com/x/icebergs"
+ "shylinux.com/x/icebergs/base/ctx"
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/nfs"
kit "shylinux.com/x/toolkits"
"shylinux.com/x/toolkits/miss"
)
-func _cache_name(m *ice.Message, h string) string {
- return path.Join(ice.VAR_FILE, h[:2], h)
-}
-func _cache_type(m *ice.Message, kind, name string) string {
- if kind == "application/octet-stream" {
+func _cache_name(m *ice.Message, h string) string { return path.Join(ice.VAR_FILE, h[:2], h) }
+func _cache_mime(m *ice.Message, mime, name string) string {
+ if mime == "application/octet-stream" {
if kit.ExtIsImage(name) {
- kind = "image/"+kit.Ext(name)
+ mime = "image/" + kit.Ext(name)
} else if kit.ExtIsVideo(name) {
- kind = "video/"+kit.Ext(name)
+ mime = "video/" + kit.Ext(name)
}
+ } else if mime == "" {
+ return kit.Ext(name)
}
- return kind
+ return mime
}
-func _cache_save(m *ice.Message, kind, name, text string, arg ...string) {
+func _cache_save(m *ice.Message, mime, name, text string, arg ...string) {
if m.Warn(name == "", ice.ErrNotValid, mdb.NAME) {
return
- }
- if len(text) > 512 || kind == nfs.GO {
+ } else if len(text) > 512 {
p := m.Cmdx(nfs.SAVE, _cache_name(m, kit.Hashs(text)), text)
text, arg = p, kit.Simple(p, len(text))
}
file, size := kit.Select("", arg, 0), kit.Int(kit.Select(kit.Format(len(text)), arg, 1))
- kind, text = _cache_type(m, kind, name), kit.Select(file, text)
- h := mdb.HashCreate(m, kit.SimpleKV("", kind, name, text), nfs.FILE, file, nfs.SIZE, size)
- m.Push(mdb.TIME, m.Time())
- m.Push(mdb.TYPE, kind)
- m.Push(mdb.NAME, name)
- m.Push(mdb.TEXT, text)
- m.Push(nfs.FILE, file)
- m.Push(nfs.SIZE, size)
- m.Push(mdb.HASH, h)
- m.Push(mdb.DATA, h)
+ mime, text = _cache_mime(m, mime, name), kit.Select(file, text)
+ m.Push(mdb.TIME, m.Time()).Push(mdb.HASH, mdb.HashCreate(m.Spawn(), kit.SimpleKV("", mime, name, text), nfs.FILE, file, nfs.SIZE, size))
+ m.Push(mdb.TYPE, mime).Push(mdb.NAME, name).Push(mdb.TEXT, text).Push(nfs.FILE, file).Push(nfs.SIZE, size)
}
-func _cache_watch(m *ice.Message, key, file string) {
+func _cache_watch(m *ice.Message, key, path string) {
mdb.HashSelect(m.Spawn(), key).Tables(func(value ice.Maps) {
if value[nfs.FILE] == "" {
- m.Cmdy(nfs.SAVE, file, value[mdb.TEXT])
+ m.Cmdy(nfs.SAVE, path, value[mdb.TEXT])
} else {
- m.Cmdy(nfs.LINK, file, value[nfs.FILE])
+ m.Cmdy(nfs.LINK, path, value[nfs.FILE])
}
})
}
-func _cache_catch(m *ice.Message, name string) (file, size string) {
- if msg := m.Cmd(nfs.DIR, name, "hash,size"); msg.Length() > 0 {
- return m.Cmdx(nfs.LINK, _cache_name(m, msg.Append(mdb.HASH)), name), msg.Append(nfs.SIZE)
+func _cache_catch(m *ice.Message, path string) (file string, size string) {
+ if msg := m.Cmd(nfs.DIR, path, "hash,size"); msg.Length() > 0 {
+ return m.Cmdx(nfs.LINK, _cache_name(m, msg.Append(mdb.HASH)), path), msg.Append(nfs.SIZE)
}
return "", "0"
}
-func _cache_upload(m *ice.Message, r *http.Request) (kind, name, file, size string) {
+func _cache_upload(m *ice.Message, r *http.Request) (mime, name, file, size string) {
if b, h, e := r.FormFile(UPLOAD); !m.Warn(e, ice.ErrNotValid, UPLOAD) {
defer b.Close()
if f, p, e := miss.CreateFile(_cache_name(m, kit.Hashs(b))); !m.Warn(e, ice.ErrNotValid, UPLOAD) {
@@ -75,11 +70,20 @@ func _cache_upload(m *ice.Message, r *http.Request) (kind, name, file, size stri
}
return "", "", "", "0"
}
-func _cache_download(m *ice.Message, r *http.Response, file string) string {
+func _cache_download(m *ice.Message, r *http.Response, file string, cb ice.Any) string {
defer r.Body.Close()
- if f, p, e := miss.CreateFile(file); m.Warn(e, ice.ErrNotValid, DOWNLOAD) {
+ if f, p, e := miss.CreateFile(file); !m.Warn(e, ice.ErrNotValid, DOWNLOAD) {
defer f.Close()
- nfs.CopyFile(m, f, r.Body, kit.Int(kit.Select("100", r.Header.Get(ContentLength))), m.OptionCB(SPIDE))
+ last, step, bufs := 0, 10, 40960
+ if cb == nil {
+ cb = func(size, total, count int) {
+ if count/step != last {
+ m.Logs(mdb.EXPORT, nfs.FILE, p, nfs.SIZE, size, mdb.TOTAL, total, mdb.COUNT, count)
+ }
+ last = count / step
+ }
+ }
+ nfs.CopyFile(m, f, r.Body, bufs, kit.Int(kit.Select("100", r.Header.Get(ContentLength))), cb)
return p
}
return ""
@@ -92,80 +96,91 @@ const (
UPLOAD = "upload"
DOWNLOAD = "download"
DISPLAY = "display"
-
- UPLOAD_WATCH = "upload_watch"
)
const CACHE = "cache"
func init() {
Index.MergeCommands(ice.Commands{
- CACHE: {Name: "cache hash auto", Help: "缓存池", Actions: ice.MergeActions(ice.Actions{
- WATCH: {Name: "watch key file", Help: "释放", Hand: func(m *ice.Message, arg ...string) {
- _cache_watch(m, arg[0], arg[1])
+ CACHE: {Name: "cache hash auto write catch upload", Help: "缓存池", Actions: ice.MergeActions(ice.Actions{
+ WATCH: {Name: "watch hash* path*", Help: "释放", Hand: func(m *ice.Message, arg ...string) {
+ _cache_watch(m, m.Option(mdb.HASH), m.Option(nfs.PATH))
}},
- 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)
+ WRITE: {Name: "write type name* text*", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
+ _cache_save(m, m.Option(mdb.TYPE), m.Option(mdb.NAME), m.Option(mdb.TEXT))
}},
- 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 path* type", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
+ file, size := _cache_catch(m, m.Option(nfs.PATH))
+ _cache_save(m, m.Option(mdb.TYPE), m.Option(nfs.PATH), "", 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)
+ UPLOAD: {Hand: func(m *ice.Message, arg ...string) {
+ mime, name, file, size := _cache_upload(m, m.R)
+ _cache_save(m, mime, 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_catch(m, _cache_download(m, r, path.Join(ice.VAR_TMP, kit.Hashs(mdb.UNIQ))))
- _cache_save(m, arg[0], arg[1], "", file, size)
+ DOWNLOAD: {Name: "download type name*", Hand: func(m *ice.Message, arg ...string) {
+ if r, ok := m.Optionv(RESPONSE).(*http.Response); !m.Warn(!ok, ice.ErrNotValid, RESPONSE) {
+ file, size := _cache_catch(m, _cache_download(m, r, path.Join(ice.VAR_TMP, kit.Hashs(mdb.UNIQ)), nil))
+ _cache_save(m, m.Option(mdb.TYPE), m.Option(mdb.NAME), "", file, size)
}
}},
- UPLOAD_WATCH: {Name: "upload_watch", Help: "上传", Hand: func(m *ice.Message, arg ...string) {
- up := kit.Simple(m.Optionv(ice.MSG_UPLOAD))
- if len(up) < 2 {
- msg := m.Cmd(CACHE, UPLOAD)
- up = kit.Simple(msg.Append(mdb.HASH), msg.Append(mdb.NAME), msg.Append(nfs.SIZE))
- }
- if p := path.Join(arg[0], up[1]); m.Option(ice.MSG_USERPOD) == "" {
- m.Cmdy(CACHE, WATCH, up[0], p)
- } else {
- m.Cmdy(SPIDE, ice.DEV, nfs.SAVE, p, SPIDE_GET, MergeURL2(m, path.Join(SHARE_CACHE, up[0])))
- }
+ ice.RENDER_DOWNLOAD: {Hand: func(m *ice.Message, arg ...string) {
+ p := kit.Select(arg[0], arg, 1)
+ p = kit.Select("", SHARE_LOCAL, !strings.HasPrefix(p, ice.PS) && !strings.HasPrefix(p, ice.HTTP)) + p
+ args := []string{ice.POD, m.Option(ice.MSG_USERPOD), "filename", kit.Select("", arg[0], len(arg) > 1)}
+ m.Echo(fmt.Sprintf(`%s`, MergeURL2(m, p, args), path.Base(arg[0]), arg[0]))
}},
- }, mdb.HashAction(mdb.SHORT, mdb.TEXT, mdb.FIELD, "time,hash,size,type,name,text,file")), Hand: func(m *ice.Message, arg ...string) {
- if mdb.HashSelect(m, arg...); len(arg) == 0 {
+ ice.PS: {Hand: func(m *ice.Message, arg ...string) {
+ mdb.HashSelectDetail(m, arg[0], func(value ice.Map) {
+ if kit.Format(value[nfs.FILE]) == "" {
+ m.RenderResult(value[mdb.TEXT])
+ } else {
+ m.RenderDownload(value[nfs.FILE])
+ }
+ })
+ }},
+ }, mdb.HashAction(mdb.SHORT, mdb.TEXT, mdb.FIELD, "time,hash,size,type,name,text,file", ctx.ACTION, WATCH), ice.RenderAction(ice.RENDER_DOWNLOAD)), Hand: func(m *ice.Message, arg ...string) {
+ if mdb.HashSelect(m, arg...); len(arg) == 0 || m.R.Method == http.MethodGet {
return
}
if m.Append(nfs.FILE) == "" {
- m.PushScript("inner", m.Append(mdb.TEXT))
+ m.PushScript(mdb.TEXT, m.Append(mdb.TEXT))
} else {
- m.PushDownload(m.Append(mdb.NAME), MergeURL2(m, SHARE_CACHE+arg[0]))
+ PushDisplay(m, m.Append(mdb.TYPE), m.Append(mdb.NAME), MergeURL2(m, SHARE_CACHE+arg[0]))
}
}},
- PP(CACHE): {Name: "/cache/", Help: "缓存池", Hand: func(m *ice.Message, arg ...string) {
- mdb.HashSelectDetail(m, arg[0], func(value ice.Map) {
- if kit.Format(value[nfs.FILE]) == "" {
- m.RenderResult(value[mdb.TEXT])
- } else {
- m.RenderDownload(value[nfs.FILE])
- }
- })
- }},
})
ice.AddMerges(func(c *ice.Context, key string, cmd *ice.Command, sub string, action *ice.Action) (ice.Handler, ice.Handler) {
switch sub {
case UPLOAD:
- if key == CACHE {
+ if c.Name == WEB && key == CACHE {
break
}
- hand := action.Hand
- action.Hand = func(m *ice.Message, arg ...string) {
- if len(kit.Simple(m.Optionv(ice.MSG_UPLOAD))) == 1 {
- m.Cmdy(CACHE, UPLOAD)
+ watch := action.Hand == nil
+ action.Hand = ice.MergeHand(func(m *ice.Message, arg ...string) {
+ up := kit.Simple(m.Optionv(ice.MSG_UPLOAD))
+ m.Assert(len(up) > 1)
+ m.Cmd(CACHE, m.Option(ice.MSG_UPLOAD)).Tables(func(value ice.Maps) { m.Options(value) })
+ if m.Options(mdb.HASH, up[0], mdb.NAME, up[1]); watch {
+ m.Cmdy(CACHE, WATCH, m.Option(mdb.HASH), path.Join(m.Option(nfs.PATH), m.Option(mdb.NAME)))
}
- hand(m, arg...)
- }
+ }, action.Hand)
}
return nil, nil
})
+ ctx.Upload = Upload
+}
+func Upload(m *ice.Message) {
+ if up := kit.Simple(m.Optionv(ice.MSG_UPLOAD)); len(up) == 1 {
+ if m.Cmdy(CACHE, UPLOAD).Optionv(ice.MSG_UPLOAD, kit.Simple(m.Append(mdb.HASH), m.Append(mdb.NAME), m.Append(nfs.SIZE))); m.Option(ice.MSG_USERPOD) != "" {
+ m.Cmd(SPACE, m.Option(ice.MSG_USERPOD), SPIDE, ice.DEV, SPIDE_CACHE, http.MethodGet, MergeURL2(m, path.Join(SHARE_CACHE, m.Append(mdb.HASH))))
+ }
+ }
+}
+func PushDisplay(m *ice.Message, mime, name, link string) {
+ if strings.HasPrefix(mime, "image/") || kit.ExtIsImage(name) {
+ m.PushImages(nfs.FILE, link)
+ } else if strings.HasPrefix(mime, "video/") || kit.ExtIsImage(name) {
+ m.PushVideos(nfs.FILE, link)
+ } else {
+ m.PushDownload(nfs.FILE, name, link)
+ }
}
diff --git a/base/web/option.go b/base/web/option.go
index e57237da..a0f74332 100644
--- a/base/web/option.go
+++ b/base/web/option.go
@@ -12,18 +12,11 @@ import (
"shylinux.com/x/icebergs/base/ctx"
"shylinux.com/x/icebergs/base/gdb"
"shylinux.com/x/icebergs/base/mdb"
- "shylinux.com/x/icebergs/base/nfs"
"shylinux.com/x/icebergs/base/tcp"
kit "shylinux.com/x/toolkits"
"shylinux.com/x/toolkits/file"
)
-func Upload(m *ice.Message) *ice.Message {
- if len(kit.Simple(m.Optionv(ice.MSG_UPLOAD))) == 1 {
- m.Cmdy(CACHE, UPLOAD).Option(ice.MSG_UPLOAD, m.Append(mdb.HASH), m.Append(mdb.NAME), m.Append(nfs.SIZE))
- }
- return m
-}
func PushNotice(m *ice.Message, arg ...ice.Any) {
if m.Option(ice.MSG_DAEMON) == "" {
return
diff --git a/base/web/route.go b/base/web/route.go
deleted file mode 100644
index 56132f79..00000000
--- a/base/web/route.go
+++ /dev/null
@@ -1,112 +0,0 @@
-package web
-
-import (
- ice "shylinux.com/x/icebergs"
- "shylinux.com/x/icebergs/base/aaa"
- "shylinux.com/x/icebergs/base/cli"
- "shylinux.com/x/icebergs/base/ctx"
- "shylinux.com/x/icebergs/base/lex"
- "shylinux.com/x/icebergs/base/mdb"
- "shylinux.com/x/icebergs/base/tcp"
- kit "shylinux.com/x/toolkits"
-)
-
-func _route_travel(m *ice.Message, route string) {
- m.Cmd(SPACE, func(val ice.Maps) {
- switch val[mdb.TYPE] {
- case SERVER: // 远程查询
- if val[mdb.NAME] == ice.Info.NodeName {
- return // 避免循环
- }
-
- m.Cmd(SPACE, val[mdb.NAME], ROUTE, func(value ice.Maps) {
- m.Push(mdb.TYPE, value[mdb.TYPE])
- m.Push(ROUTE, kit.Keys(val[mdb.NAME], value[ROUTE]))
- })
- fallthrough
- case WORKER: // 本机查询
- m.Push(mdb.TYPE, val[mdb.TYPE])
- m.Push(ROUTE, val[mdb.NAME])
- }
- })
-}
-func _route_list(m *ice.Message) *ice.Message {
- m.Tables(func(value ice.Maps) {
- switch m.PushAnchor(value[ROUTE], MergePod(m, value[ROUTE])); value[mdb.TYPE] {
- case SERVER:
- m.PushButton(tcp.START, aaa.INVITE)
- case WORKER:
- fallthrough
- default:
- m.PushButton("")
- }
- })
-
- // 网卡信息
- u := OptionUserWeb(m)
- m.Cmd(tcp.HOST, func(value ice.Maps) {
- m.Push(mdb.TYPE, MYSELF)
- m.Push(ROUTE, ice.Info.NodeName)
- m.PushAnchor(value[aaa.IP], kit.Format("%s://%s:%s", u.Scheme, value[aaa.IP], u.Port()))
- m.PushButton(tcp.START)
- })
-
- // 本机信息
- m.Push(mdb.TYPE, MYSELF)
- m.Push(ROUTE, ice.Info.NodeName)
- m.PushAnchor(tcp.LOCALHOST, kit.Format("%s://%s:%s", u.Scheme, tcp.LOCALHOST, u.Port()))
- m.PushButton(tcp.START)
- return m
-}
-
-const ROUTE = "route"
-
-func init() {
- Index.MergeCommands(ice.Commands{
- ROUTE: {Name: "route route index auto invite spide", Help: "路由器", Actions: ice.Actions{
- aaa.INVITE: {Name: "invite", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
- m.Cmdy(SPACE, m.Option(ROUTE), SPACE, aaa.INVITE, arg).ProcessInner()
- }},
- cli.START: {Name: "start name repos template", Help: "启动", Hand: func(m *ice.Message, arg ...string) {
- m.Cmdy(SPACE, m.Option(ROUTE), DREAM, tcp.START, arg).ProcessInner()
- }},
- ctx.COMMAND: {Name: "command", Help: "命令", Hand: func(m *ice.Message, arg ...string) {
- m.Cmdy(SPACE, m.Option(ROUTE), m.Option(ctx.INDEX), arg)
- }},
- ice.RUN: {Name: "run", Help: "执行", Hand: func(m *ice.Message, arg ...string) {
- m.Cmdy(SPACE, m.Option(ROUTE), arg)
- }},
- SPIDE: {Name: "spide", Help: "架构图", Hand: func(m *ice.Message, arg ...string) {
- if m.Option(ROUTE) == "" { // 路由列表 route
- ctx.DisplayStorySpide(m, lex.PREFIX, SPIDE, lex.SPLIT, ice.PT)
- m.Cmdy(ROUTE).Cut(ROUTE)
-
- } else if m.Option(ctx.CONTEXT) == "" { // 模块列表 context
- m.Cmdy(SPACE, m.Option(ROUTE), ctx.CONTEXT, ice.ICE, ctx.CONTEXT).Cut(mdb.NAME).RenameAppend(mdb.NAME, ctx.CONTEXT)
- m.Option(lex.SPLIT, ice.PT)
-
- } else if m.Option(mdb.NAME) == "" { // 命令列表 name
- m.Cmdy(SPACE, m.Option(ROUTE), ctx.CONTEXT, SPIDE, "", m.Option(ctx.CONTEXT), m.Option(ctx.CONTEXT)).Cut(mdb.NAME)
-
- } else { // 命令详情 index name help meta list
- m.Cmdy(SPACE, m.Option(ROUTE), ctx.CONTEXT, SPIDE, "", m.Option(ctx.CONTEXT), m.Option(mdb.NAME))
- }
- }},
- }, Hand: func(m *ice.Message, arg ...string) {
- if len(arg) == 0 || arg[0] == "" { // 路由列表
- if _route_travel(m, kit.Select("", arg, 0)); m.W != nil {
- _route_list(m).Sort("type,route")
- }
-
- } else if len(arg) == 1 || arg[1] == "" { // 模块列表
- m.Cmd(SPACE, arg[0], ctx.COMMAND, mdb.SEARCH, ctx.COMMAND, ice.OptionFields(ctx.INDEX, mdb.NAME, mdb.HELP)).Table(func(index int, value ice.Maps, head []string) {
- m.Push("", value, head)
- })
-
- } else { // 命令详情
- m.Cmdy(SPACE, arg[0], ctx.COMMAND, arg[1])
- m.ProcessField(ctx.ACTION, ctx.COMMAND)
- }
- }},
- })
-}
diff --git a/base/web/serve.go b/base/web/serve.go
index cd609da1..2b2a4526 100644
--- a/base/web/serve.go
+++ b/base/web/serve.go
@@ -56,10 +56,12 @@ func _serve_main(m *ice.Message, w http.ResponseWriter, r *http.Request) bool {
if m.Logs(r.Method, r.Header.Get(ice.MSG_USERIP), r.URL.String()); m.Config(LOGHEADERS) == ice.TRUE {
kit.Fetch(r.Header, func(k string, v []string) { m.Logs("Header", k, v) })
}
- repos := kit.Select(ice.INTSHELL, ice.VOLCANOS, strings.Contains(r.Header.Get(UserAgent), MOZILLA))
- if msg := gdb.Event(m.Spawn(w, r), SERVE_REWRITE, r.Method, r.URL.Path, path.Join(m.Conf(SERVE, kit.Keym(repos, nfs.PATH)), r.URL.Path), repos); msg.Option(ice.MSG_OUTPUT) != "" {
- Render(msg, msg.Option(ice.MSG_OUTPUT), kit.List(msg.Optionv(ice.MSG_ARGS))...)
- return false
+ if r.Method == http.MethodGet {
+ repos := kit.Select(ice.INTSHELL, ice.VOLCANOS, strings.Contains(r.Header.Get(UserAgent), MOZILLA))
+ if msg := gdb.Event(m.Spawn(w, r), SERVE_REWRITE, r.Method, r.URL.Path, path.Join(m.Conf(SERVE, kit.Keym(repos, nfs.PATH)), r.URL.Path), repos); msg.Option(ice.MSG_OUTPUT) != "" {
+ Render(msg, msg.Option(ice.MSG_OUTPUT), kit.List(msg.Optionv(ice.MSG_ARGS))...)
+ return false
+ }
}
return true
}
@@ -106,7 +108,6 @@ func _serve_handle(key string, cmd *ice.Command, m *ice.Message, w http.Response
m.CmdHand(cmd, key, cmds...)
}
}
- gdb.Event(m, SERVE_RENDER, m.Option(ice.MSG_OUTPUT))
Render(m, m.Option(ice.MSG_OUTPUT), m.Optionv(ice.MSG_ARGS))
}
func _serve_domain(m *ice.Message) string {
@@ -227,12 +228,20 @@ func init() {
m.Cmdy("web.chat./cmd/", arg)
}},
})
- ice.AddMerges(func(ctx *ice.Context, key string, cmd *ice.Command, sub string, action *ice.Action) (ice.Handler, ice.Handler) {
+ ice.AddMerges(func(c *ice.Context, key string, cmd *ice.Command, sub string, action *ice.Action) (ice.Handler, ice.Handler) {
if strings.HasPrefix(sub, ice.PS) {
if sub = kit.Select(sub, PP(key), sub == ice.PS); action.Hand == nil {
action.Hand = func(m *ice.Message, arg ...string) { m.Cmdy(key, arg) }
}
- ctx.Commands[sub] = &ice.Command{Name: sub, Help: cmd.Help, Actions: cmd.Actions, Hand: action.Hand}
+ // c.Commands[sub] = &ice.Command{Name: sub, Help: cmd.Help, Actions: cmd.Actions, Hand: action.Hand}
+ actions := ice.Actions{}
+ for k, v := range cmd.Actions {
+ switch k {
+ case ctx.COMMAND, ice.RUN:
+ actions[k] = v
+ }
+ }
+ c.Commands[sub] = &ice.Command{Name: sub, Help: cmd.Help, Actions: actions, Hand: action.Hand}
}
return nil, nil
})
diff --git a/base/web/share.go b/base/web/share.go
index 96c35079..e18ceaa7 100644
--- a/base/web/share.go
+++ b/base/web/share.go
@@ -1,7 +1,6 @@
package web
import (
- "fmt"
"net/http"
"path"
"strings"
@@ -19,16 +18,8 @@ import (
"shylinux.com/x/toolkits/logs"
)
-func _share_render(m *ice.Message, arg ...string) {
- ice.AddRender(ice.RENDER_DOWNLOAD, func(msg *ice.Message, arg ...ice.Any) string {
- args := kit.Simple(arg...)
- list := []string{ice.POD, msg.Option(ice.MSG_USERPOD), "filename", kit.Select("", args[0], len(args) > 1)}
- return fmt.Sprintf(`%s`, _share_link(msg, kit.Select(args[0], args, 1), list), path.Base(args[0]), args[0])
- })
-}
-func _share_link(m *ice.Message, p string, arg ...ice.Any) string {
- p = kit.Select("", SHARE_LOCAL, !strings.HasPrefix(p, ice.PS) && !strings.HasPrefix(p, ice.HTTP)) + p
- return tcp.PublishLocalhost(m, MergeLink(m, p, arg...))
+func _share_link(m *ice.Message, p string) string {
+ return tcp.PublishLocalhost(m, MergeLink(m, kit.Select("", SHARE_LOCAL, !strings.HasPrefix(p, ice.PS) && !strings.HasPrefix(p, ice.HTTP))+p))
}
func _share_cache(m *ice.Message, arg ...string) {
if pod := m.Option(ice.POD); ctx.PodCmd(m, CACHE, arg[0]) {
@@ -39,8 +30,11 @@ func _share_cache(m *ice.Message, arg ...string) {
_share_local(m, m.Append(nfs.FILE))
}
} else {
- msg := m.Cmd(CACHE, arg[0])
- m.RenderDownload(msg.Append(nfs.FILE), msg.Append(mdb.TYPE), msg.Append(mdb.NAME))
+ if m.Cmdy(CACHE, arg[0]); m.Append(nfs.FILE) == "" {
+ m.RenderResult(m.Append(mdb.TEXT))
+ } else {
+ m.RenderDownload(m.Append(nfs.FILE), m.Append(mdb.TYPE), m.Append(mdb.NAME))
+ }
}
}
func _share_local(m *ice.Message, arg ...string) {
@@ -65,11 +59,9 @@ func _share_local(m *ice.Message, arg ...string) {
cache, size = s.ModTime(), s.Size()
}
if p == ice.BIN_ICE_BIN {
- aaa.UserRoot(m).Cmd(SPACE, m.Option(ice.POD), SPIDE, "submit", MergeURL2(m, SHARE_PROXY, nfs.PATH, ""), m.Option(ice.POD), p, size, cache.Format(ice.MOD_TIME))
- } else {
- m.Cmd(SPACE, m.Option(ice.POD), SPIDE, ice.DEV, SPIDE_RAW, MergeURL2(m, SHARE_PROXY, nfs.PATH, ""),
- SPIDE_PART, m.OptionSimple(ice.POD), nfs.PATH, p, nfs.SIZE, size, CACHE, cache.Format(ice.MOD_TIME), UPLOAD, "@"+p)
+ m.Option(ice.MSG_USERROLE, aaa.TECH)
}
+ m.Cmd(SPACE, m.Option(ice.POD), SPIDE, ice.DEV, SPIDE_RAW, MergeLink(m, SHARE_PROXY), SPIDE_PART, m.OptionSimple(ice.POD), nfs.PATH, p, nfs.SIZE, size, CACHE, cache.Format(ice.MOD_TIME), UPLOAD, "@"+p)
if !m.Warn(!file.ExistsFile(pp), ice.ErrNotFound, pp) {
m.RenderDownload(pp)
}
@@ -77,10 +69,11 @@ func _share_local(m *ice.Message, arg ...string) {
func _share_proxy(m *ice.Message) {
switch p := path.Join(ice.VAR_PROXY, m.Option(ice.POD), m.Option(nfs.PATH)); m.R.Method {
case http.MethodGet:
- m.RenderDownload(path.Join(p, m.Option(mdb.NAME)))
+ m.RenderDownload(p, m.Option(mdb.TYPE), m.Option(mdb.NAME))
case http.MethodPost:
- m.Cmdy(CACHE, UPLOAD)
- m.Cmdy(CACHE, WATCH, m.Option(mdb.DATA), p)
+ if _, _, e := m.R.FormFile(UPLOAD); e == nil {
+ m.Cmdy(CACHE, UPLOAD).Cmdy(CACHE, WATCH, m.Option(mdb.HASH), p)
+ }
m.RenderResult(m.Option(nfs.PATH))
}
}
@@ -92,11 +85,10 @@ const (
STORM = "storm"
FIELD = "field"
- SHARE_TOAST = "/share/toast/"
SHARE_CACHE = "/share/cache/"
SHARE_LOCAL = "/share/local/"
SHARE_PROXY = "/share/proxy/"
- SHARE_REPOS = "/share/repos/"
+ SHARE_TOAST = "/share/toast/"
SHARE_LOCAL_AVATAR = "/share/local/avatar/"
SHARE_LOCAL_BACKGROUND = "/share/local/background/"
@@ -105,24 +97,17 @@ const SHARE = "share"
func init() {
Index.MergeCommands(ice.Commands{
- SHARE: {Name: "share hash auto prunes", Help: "共享链", Actions: ice.MergeActions(ice.Actions{
- ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { _share_render(m) }},
+ SHARE: {Name: "share hash auto login prunes", Help: "共享链", Actions: ice.MergeActions(ice.Actions{
mdb.CREATE: {Name: "create type name text", Hand: func(m *ice.Message, arg ...string) {
mdb.HashCreate(m, arg, aaa.USERNAME, m.Option(ice.MSG_USERNAME), aaa.USERNICK, m.Option(ice.MSG_USERNICK), aaa.USERROLE, m.Option(ice.MSG_USERROLE))
- m.Option(mdb.LINK, _share_link(m, PP(SHARE)+m.Result()))
+ m.Option(mdb.LINK, _share_link(m, P(SHARE, m.Result())))
}},
- LOGIN: {Name: "login userrole=void,tech username", Hand: func(m *ice.Message, arg ...string) {
+ LOGIN: {Hand: func(m *ice.Message, arg ...string) {
m.EchoQRCode(m.Cmd(SHARE, mdb.CREATE, mdb.TYPE, LOGIN).Option(mdb.LINK)).ProcessInner()
}},
SERVE_PARSE: {Hand: func(m *ice.Message, arg ...string) {
- if kit.Select("", arg, 0) != SHARE {
- return
- }
- switch arg[1] {
- case "local":
- default:
- m.Logs("Refer", arg[0], arg[1])
- m.Option(arg[0], arg[1])
+ if kit.Select("", arg, 0) == SHARE {
+ m.Logs("Refer", arg[0], arg[1]).Option(arg[0], arg[1])
}
}},
SERVE_LOGIN: {Hand: func(m *ice.Message, arg ...string) {
@@ -133,6 +118,23 @@ func init() {
}
}
}},
+ ice.PS: {Hand: func(m *ice.Message, arg ...string) {
+ if m.Warn(len(arg) == 0 || arg[0] == "", ice.ErrNotValid, SHARE) {
+ return
+ }
+ msg := m.Cmd(SHARE, m.Option(SHARE, arg[0]))
+ if IsNotValidShare(m, msg.Append(mdb.TIME)) {
+ m.RenderResult(kit.Format("共享超时, 请联系 %s(%s), 重新分享 %s %s",
+ msg.Append(aaa.USERNAME), msg.Append(aaa.USERNICK), msg.Append(mdb.TYPE), msg.Append(mdb.NAME)))
+ return
+ }
+ switch msg.Append(mdb.TYPE) {
+ case LOGIN:
+ m.RenderRedirect(ice.PS, ice.MSG_SESSID, aaa.SessCreate(m, msg.Append(aaa.USERNAME)))
+ default:
+ RenderIndex(m, "")
+ }
+ }},
}, mdb.HashAction(mdb.FIELD, "time,hash,username,usernick,userrole,river,storm,type,name,text", mdb.EXPIRE, "72h"), ServeAction(), aaa.WhiteAction()), Hand: func(m *ice.Message, arg ...string) {
if ctx.PodCmd(m, SHARE, arg) {
return
@@ -142,45 +144,20 @@ func init() {
m.PushQRCode(cli.QRCODE, link)
m.PushScript(nfs.SCRIPT, link)
m.PushAnchor(link)
- } else {
- m.Action(LOGIN)
}
}},
- PP(SHARE): {Name: "/share/", Help: "共享链", Hand: func(m *ice.Message, arg ...string) {
- msg := m.Cmd(SHARE, m.Option(SHARE, kit.Select(m.Option(SHARE), arg, 0)))
- if IsNotValidShare(m, msg.Append(mdb.TIME)) {
- m.RenderResult(kit.Format("共享超时, 请联系 %s(%s), 重新分享 %s %s",
- msg.Append(aaa.USERNAME), msg.Append(aaa.USERNICK), msg.Append(mdb.TYPE), msg.Append(mdb.NAME)))
- return
- }
- switch msg.Append(mdb.TYPE) {
- case LOGIN:
- m.RenderRedirect(ice.PS, ice.MSG_SESSID, aaa.SessCreate(m, msg.Append(aaa.USERNAME)))
- default:
- RenderIndex(m, ice.VOLCANOS)
- }
- }},
- SHARE_TOAST: {Name: "/share/toast/", Help: "推送流", Hand: func(m *ice.Message, arg ...string) {
- m.Cmdy(SPACE, m.Option(ice.POD), m.Optionv("cmds"))
- }},
- SHARE_CACHE: {Name: "/share/cache/", Help: "缓存池", Hand: func(m *ice.Message, arg ...string) {
- _share_cache(m, arg...)
- }},
- SHARE_LOCAL: {Name: "/share/local/", Help: "文件夹", Hand: func(m *ice.Message, arg ...string) {
- _share_local(m, arg...)
- }},
- SHARE_LOCAL_AVATAR: {Name: "avatar", Help: "头像", Hand: func(m *ice.Message, arg ...string) {
+ SHARE_CACHE: {Hand: func(m *ice.Message, arg ...string) { _share_cache(m, arg...) }},
+ SHARE_LOCAL: {Hand: func(m *ice.Message, arg ...string) { _share_local(m, arg...) }},
+ SHARE_LOCAL_AVATAR: {Hand: func(m *ice.Message, arg ...string) {
m.RenderDownload(strings.TrimPrefix(m.CmdAppend(aaa.USER, m.Option(ice.MSG_USERNAME), aaa.AVATAR), SHARE_LOCAL))
}},
- SHARE_LOCAL_BACKGROUND: {Name: "background", Help: "背景", Hand: func(m *ice.Message, arg ...string) {
+ SHARE_LOCAL_BACKGROUND: {Hand: func(m *ice.Message, arg ...string) {
m.RenderDownload(strings.TrimPrefix(m.CmdAppend(aaa.USER, m.Option(ice.MSG_USERNAME), aaa.BACKGROUND), SHARE_LOCAL))
}},
- SHARE_PROXY: {Name: "/share/proxy/", Help: "文件流", Hand: func(m *ice.Message, arg ...string) {
- _share_proxy(m)
- }},
+ SHARE_PROXY: {Hand: func(m *ice.Message, arg ...string) { _share_proxy(m) }},
+ SHARE_TOAST: {Hand: func(m *ice.Message, arg ...string) { m.Cmdy(SPACE, m.Option(ice.POD), m.Optionv("cmds")) }},
})
}
-
func IsNotValidShare(m *ice.Message, time string) bool {
return m.Warn(time < m.Time(), ice.ErrNotValid, m.Option(SHARE), time, m.Time(), logs.FileLineMeta(2))
}
diff --git a/base/web/space.go b/base/web/space.go
index cbe2a307..f1acbe75 100644
--- a/base/web/space.go
+++ b/base/web/space.go
@@ -9,6 +9,7 @@ import (
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/aaa"
"shylinux.com/x/icebergs/base/cli"
+ "shylinux.com/x/icebergs/base/ctx"
"shylinux.com/x/icebergs/base/gdb"
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/tcp"
@@ -178,8 +179,9 @@ func init() {
aaa.SessAuth(m, kit.Dict(aaa.USERNAME, m.Option(ice.MSG_USERNAME), aaa.USERNICK, m.Option(ice.MSG_USERNICK), aaa.USERROLE, m.Option(ice.MSG_USERROLE)))
}},
DOMAIN: {Hand: func(m *ice.Message, arg ...string) { m.Echo(_space_domain(m)) }},
+ OPEN: {Hand: func(m *ice.Message, arg ...string) { ctx.ProcessOpen(m, MergePod(m, m.Option(mdb.NAME), arg)) }},
ice.PS: {Hand: func(m *ice.Message, arg ...string) { _space_fork(m) }},
- }, mdb.HashAction(mdb.SHORT, mdb.NAME, mdb.FIELD, "time,type,name,text",
+ }, mdb.HashAction(mdb.SHORT, mdb.NAME, mdb.FIELD, "time,type,name,text", ctx.ACTION, OPEN,
REDIAL, kit.Dict("a", 3000, "b", 1000, "c", 1000), TIMEOUT, kit.Dict("c", "30s"),
BUFFER, kit.Dict("r", ice.MOD_BUFS, "w", ice.MOD_BUFS),
), mdb.ClearHashOnExitAction(), SpaceAction(), aaa.WhiteAction()), Hand: func(m *ice.Message, arg ...string) {
@@ -224,5 +226,9 @@ func back(m *ice.Message, res *ice.Message) bool {
}
return false
}
-func addSend(m *ice.Message, msg *ice.Message) string { return m.Target().Server().(*Frame).addSend(kit.Format(m.Target().ID()), msg) }
-func getSend(m *ice.Message, key string) *ice.Message { return m.Target().Server().(*Frame).getSend(key) }
+func addSend(m *ice.Message, msg *ice.Message) string {
+ return m.Target().Server().(*Frame).addSend(kit.Format(m.Target().ID()), msg)
+}
+func getSend(m *ice.Message, key string) *ice.Message {
+ return m.Target().Server().(*Frame).getSend(key)
+}
diff --git a/base/web/spide.go b/base/web/spide.go
index 5a822393..fdd34cb9 100644
--- a/base/web/spide.go
+++ b/base/web/spide.go
@@ -13,7 +13,6 @@ import (
"time"
ice "shylinux.com/x/icebergs"
- "shylinux.com/x/icebergs/base/aaa"
"shylinux.com/x/icebergs/base/cli"
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/nfs"
@@ -22,8 +21,7 @@ import (
)
func _spide_create(m *ice.Message, name, address string) {
- // if uri, e := url.Parse(address); !m.Warn(e != nil || address == "", address) {
- if uri, e := url.Parse(address); m.Assert(e == nil) {
+ if uri, e := url.Parse(address); !m.Warn(e != nil || address == "", address) {
m.Logs(mdb.CREATE, SPIDE, name, ADDRESS, address)
dir, file := path.Split(uri.EscapedPath())
mdb.HashCreate(m, CLIENT_NAME, name)
@@ -37,15 +35,14 @@ func _spide_create(m *ice.Message, name, address string) {
})
}
}
-func _spide_list(m *ice.Message, arg ...string) {
+func _spide_show(m *ice.Message, arg ...string) {
msg := mdb.HashSelects(m.Spawn(), arg[0])
if len(arg) == 2 && msg.Append(arg[1]) != "" {
m.Echo(msg.Append(arg[1]))
return
}
-
cache, save := "", ""
- switch arg[1] { // 缓存方法
+ switch arg[1] {
case SPIDE_RAW:
cache, arg = arg[1], arg[1:]
case SPIDE_MSG:
@@ -55,9 +52,8 @@ func _spide_list(m *ice.Message, arg ...string) {
case SPIDE_CACHE:
cache, arg = arg[1], arg[1:]
}
-
method := kit.Select(SPIDE_POST, msg.Append(CLIENT_METHOD))
- switch arg = arg[1:]; arg[0] { // 请求方法
+ switch arg = arg[1:]; arg[0] {
case SPIDE_GET:
method, arg = SPIDE_GET, arg[1:]
case SPIDE_PUT:
@@ -67,44 +63,30 @@ func _spide_list(m *ice.Message, arg ...string) {
case SPIDE_DELETE:
method, arg = SPIDE_DELETE, arg[1:]
}
-
- // 构造请求
uri, arg := arg[0], arg[1:]
body, head, arg := _spide_body(m, method, arg...)
req, e := http.NewRequest(method, kit.MergeURL2(msg.Append(CLIENT_URL), uri, arg), body)
if m.Warn(e, ice.ErrNotValid, uri) {
return
}
-
- // 请求变量
- mdb.HashSelectDetail(m, msg.Append(CLIENT_NAME), func(value ice.Map) {
- _spide_head(m, req, head, value)
- })
-
- // 发送请求
+ mdb.HashSelectDetail(m, msg.Append(CLIENT_NAME), func(value ice.Map) { _spide_head(m, req, head, value) })
res, e := _spide_send(m, msg.Append(CLIENT_NAME), req, kit.Format(msg.Append(CLIENT_TIMEOUT)))
if m.Warn(e, ice.ErrNotFound, uri) {
return
}
defer res.Body.Close()
-
- // 请求日志
if m.Config(LOGHEADERS) == ice.TRUE {
for k, v := range res.Header {
m.Logs(mdb.IMPORT, k, v)
}
}
m.Cost(cli.STATUS, res.Status, nfs.SIZE, res.Header.Get(ContentLength), mdb.TYPE, res.Header.Get(ContentType))
-
- // 响应变量
mdb.HashSelectUpdate(m, msg.Append(CLIENT_NAME), func(value ice.Map) {
for _, v := range res.Cookies() {
kit.Value(value, kit.Keys(SPIDE_COOKIE, v.Name), v.Value)
m.Logs(mdb.IMPORT, v.Name, v.Value)
}
})
-
- // 处理异常
if m.Warn(res.StatusCode != http.StatusOK, ice.ErrNotValid, uri, cli.STATUS, res.Status) {
switch m.SetResult(); res.StatusCode {
case http.StatusNotFound:
@@ -115,8 +97,6 @@ func _spide_list(m *ice.Message, arg ...string) {
return
}
}
-
- // 解析结果
_spide_save(m, cache, save, uri, res)
}
func _spide_body(m *ice.Message, method string, arg ...string) (io.Reader, ice.Maps, []string) {
@@ -128,42 +108,23 @@ func _spide_body(m *ice.Message, method string, arg ...string) (io.Reader, ice.M
}
switch arg[0] {
case SPIDE_FORM:
- data := []string{}
- for i := 1; i < len(arg)-1; i += 2 {
- data = append(data, url.QueryEscape(arg[i])+"="+url.QueryEscape(arg[i+1]))
- }
- body = bytes.NewBufferString(strings.Join(data, "&"))
- head[ContentType] = ContentFORM
-
+ arg = kit.Simple(arg, func(v string) string { return url.QueryEscape(v) })
+ head[ContentType], body = ContentFORM, bytes.NewBufferString(kit.JoinKV("=", "&", arg[1:]...))
case SPIDE_PART:
- body, head[ContentType] = _spide_part(m, arg...)
-
+ head[ContentType], body = _spide_part(m, arg...)
case SPIDE_DATA:
- if len(arg) == 1 {
- arg = append(arg, "{}")
- }
- body, arg = bytes.NewBufferString(arg[1]), arg[2:]
- head[ContentType] = ContentJSON
-
+ head[ContentType], body = ContentJSON, bytes.NewBufferString(kit.Select("{}", arg, 1))
case SPIDE_FILE:
if f, e := nfs.OpenFile(m, arg[1]); m.Assert(e) {
- defer f.Close()
- body, arg = f, arg[2:]
+ body = f
}
-
case SPIDE_JSON:
arg = arg[1:]
fallthrough
default:
data := ice.Map{}
- for i := 0; i < len(arg)-1; i += 2 {
- kit.Value(data, arg[i], arg[i+1])
- }
- if b, e := json.Marshal(data); m.Assert(e) {
- head[ContentType] = ContentJSON
- body = bytes.NewBuffer(b)
- }
- m.Logs(mdb.EXPORT, SPIDE_JSON, kit.Format(data))
+ kit.Fetch(arg, func(k, v string) { kit.Value(data, k, v) })
+ head[ContentType], body = ContentJSON, bytes.NewBufferString(kit.Format(data))
}
arg = arg[:0]
} else {
@@ -171,33 +132,29 @@ func _spide_body(m *ice.Message, method string, arg ...string) (io.Reader, ice.M
}
return body, head, arg
}
-func _spide_part(m *ice.Message, arg ...string) (io.Reader, string) {
+func _spide_part(m *ice.Message, arg ...string) (string, io.Reader) {
buf := &bytes.Buffer{}
mp := multipart.NewWriter(buf)
defer mp.Close()
-
- cache := time.Now().Add(-time.Hour * 240000)
- var size int64
+ size, cache := int64(0), time.Now().Add(-time.Hour*240000)
for i := 1; i < len(arg)-1; i += 2 {
if arg[i] == nfs.SIZE {
size = kit.Int64(arg[i+1])
- }
- if arg[i] == SPIDE_CACHE {
+ } else if arg[i] == SPIDE_CACHE {
if t, e := time.ParseInLocation(ice.MOD_TIME, arg[i+1], time.Local); e == nil {
cache = t
}
- }
- if strings.HasPrefix(arg[i+1], "@") {
+ } else if strings.HasPrefix(arg[i+1], ice.AT) {
if s, e := nfs.StatFile(m, arg[i+1][1:]); e == nil {
- m.Logs(mdb.IMPORT, "local", s.ModTime(), nfs.SIZE, s.Size(), CACHE, cache, nfs.SIZE, size)
if s.Size() == size && s.ModTime().Before(cache) {
- // break
+ continue
}
+ m.Logs(mdb.IMPORT, "local", s.ModTime(), nfs.SIZE, s.Size(), CACHE, cache, nfs.SIZE, size)
}
- if f, e := nfs.OpenFile(m, arg[i+1][1:]); m.Assert(e) {
+ if f, e := nfs.OpenFile(m, arg[i+1][1:]); !m.Warn(e, ice.ErrNotValid, arg[i+1]) {
defer f.Close()
- if p, e := mp.CreateFormFile(arg[i], path.Base(arg[i+1][1:])); m.Assert(e) {
- if n, e := io.Copy(p, f); m.Assert(e) {
+ if p, e := mp.CreateFormFile(arg[i], path.Base(arg[i+1][1:])); !m.Warn(e, ice.ErrNotValid, arg[i+1]) {
+ if n, e := io.Copy(p, f); !m.Warn(e, ice.ErrNotValid, arg[i+1]) {
m.Logs(mdb.EXPORT, nfs.FILE, arg[i+1], nfs.SIZE, n)
}
}
@@ -206,34 +163,32 @@ func _spide_part(m *ice.Message, arg ...string) (io.Reader, string) {
mp.WriteField(arg[i], arg[i+1])
}
}
- return buf, mp.FormDataContentType()
+ return mp.FormDataContentType(), buf
}
func _spide_head(m *ice.Message, req *http.Request, head ice.Maps, value ice.Map) {
- m.Info("%s %s", req.Method, req.URL)
- kit.Fetch(value[SPIDE_HEADER], func(key string, value string) {
- req.Header.Set(key, value)
- m.Logs(key, value)
- })
- kit.Fetch(value[SPIDE_COOKIE], func(key string, value string) {
- req.AddCookie(&http.Cookie{Name: key, Value: value})
- m.Logs(key, value)
- })
- list := kit.Simple(m.Optionv(SPIDE_COOKIE))
- for i := 0; i < len(list)-1; i += 2 {
- req.AddCookie(&http.Cookie{Name: list[i], Value: list[i+1]})
- m.Logs(list[i], list[i+1])
- }
-
- list = kit.Simple(m.Optionv(SPIDE_HEADER))
- for i := 0; i < len(list)-1; i += 2 {
- req.Header.Set(list[i], list[i+1])
- m.Logs(list[i], list[i+1])
- }
- for k, v := range head {
+ m.Logs(req.Method, req.URL)
+ kit.Fetch(value[SPIDE_HEADER], func(k string, v string) {
req.Header.Set(k, v)
- }
+ m.Logs("Header", k, v)
+ })
+ kit.Fetch(value[SPIDE_COOKIE], func(k string, v string) {
+ req.AddCookie(&http.Cookie{Name: k, Value: v})
+ m.Logs("Cookie", k, v)
+ })
+ kit.Fetch(kit.Simple(m.Optionv(SPIDE_COOKIE)), func(k, v string) {
+ req.AddCookie(&http.Cookie{Name: k, Value: v})
+ m.Logs("Cookie", k, v)
+ })
+ kit.Fetch(kit.Simple(m.Optionv(SPIDE_HEADER)), func(k, v string) {
+ req.Header.Set(k, v)
+ m.Logs("Header", k, v)
+ })
+ kit.Fetch(head, func(k, v string) {
+ req.Header.Set(k, v)
+ m.Logs("Header", k, v)
+ })
if req.Method == SPIDE_POST {
- m.Logs(req.Header.Get(ContentLength), req.Header.Get(ContentType))
+ m.Logs(kit.Select(ice.AUTO, req.Header.Get(ContentLength)), req.Header.Get(ContentType))
}
}
func _spide_send(m *ice.Message, name string, req *http.Request, timeout string) (*http.Response, error) {
@@ -243,80 +198,53 @@ func _spide_send(m *ice.Message, name string, req *http.Request, timeout string)
func _spide_save(m *ice.Message, cache, save, uri string, res *http.Response) {
switch cache {
case SPIDE_RAW:
- b, _ := ioutil.ReadAll(res.Body)
- if strings.HasPrefix(res.Header.Get(ContentType), ContentJSON) {
+ if b, _ := ioutil.ReadAll(res.Body); strings.HasPrefix(res.Header.Get(ContentType), ContentJSON) {
m.Echo(kit.Formats(kit.UnMarshal(string(b))))
} else {
m.Echo(string(b))
}
-
case SPIDE_MSG:
var data map[string][]string
m.Assert(json.NewDecoder(res.Body).Decode(&data))
- for _, k := range data[ice.MSG_APPEND] {
- for i := range data[k] {
- m.Push(k, data[k][i])
- }
- }
+ kit.Fetch(data[ice.MSG_APPEND], func(k string) { kit.Fetch(data[k], func(v string) { m.Push(k, v) }) })
m.Resultv(data[ice.MSG_RESULT])
-
case SPIDE_SAVE:
- _cache_download(m, res, save)
-
+ _cache_download(m, res, save, m.OptionCB(SPIDE))
case SPIDE_CACHE:
m.Optionv(RESPONSE, res)
m.Cmdy(CACHE, DOWNLOAD, res.Header.Get(ContentType), uri)
m.Echo(m.Append(mdb.DATA))
-
default:
- b, _ := ioutil.ReadAll(res.Body)
-
var data ice.Any
- if e := json.Unmarshal(b, &data); e != nil {
- m.Echo(string(b))
- break
+ if b, e := ioutil.ReadAll(res.Body); !m.Warn(e) {
+ if json.Unmarshal(b, &data) == nil {
+ m.Push("", kit.KeyValue(ice.Map{}, "", m.Optionv(SPIDE_RES, data)))
+ } else {
+ m.Echo(string(b))
+ }
}
-
- m.Optionv(SPIDE_RES, data)
- data = kit.KeyValue(ice.Map{}, "", data)
- m.Push("", data)
}
}
-func _cache_download(m *ice.Message, r *http.Response, file string) string {
- defer r.Body.Close()
- if f, p, e := miss.CreateFile(file); m.Warn(e, ice.ErrNotValid, DOWNLOAD) {
- defer f.Close()
- nfs.CopyFile(m, f, r.Body, kit.Int(kit.Select("100", r.Header.Get(ContentLength))), m.OptionCB(SPIDE))
- return p
- }
- return ""
-}
const (
- // 缓存方法
SPIDE_RAW = "raw"
SPIDE_MSG = "msg"
SPIDE_SAVE = "save"
SPIDE_CACHE = "cache"
- // 请求方法
- SPIDE_GET = "GET"
- SPIDE_PUT = "PUT"
- SPIDE_POST = "POST"
- SPIDE_DELETE = "DELETE"
+ SPIDE_GET = http.MethodGet
+ SPIDE_PUT = http.MethodPut
+ SPIDE_POST = http.MethodPost
+ SPIDE_DELETE = http.MethodDelete
- // 请求参数
SPIDE_BODY = "body"
SPIDE_FORM = "form"
SPIDE_PART = "part"
SPIDE_JSON = "json"
SPIDE_DATA = "data"
SPIDE_FILE = "file"
+ SPIDE_RES = "content_data"
- // 响应数据
- SPIDE_RES = "content_data"
-
- // 请求头
Bearer = "Bearer"
Authorization = "Authorization"
ContentType = "Content-Type"
@@ -325,7 +253,6 @@ const (
Referer = "Referer"
Accept = "Accept"
- // 数据格式
ContentFORM = "application/x-www-form-urlencoded"
ContentJSON = "application/json"
ContentPNG = "image/png"
@@ -338,6 +265,9 @@ const (
SPIDE_HEADER = "header"
SPIDE_COOKIE = "cookie"
+ CLIENT_PROTOCOL = "client.protocol"
+ CLIENT_HOSTNAME = "client.hostname"
+
CLIENT_NAME = "client.name"
CLIENT_METHOD = "client.method"
CLIENT_TIMEOUT = "client.timeout"
@@ -349,12 +279,10 @@ const (
LINK = "link"
HTTP = "http"
FORM = "form"
+ MERGE = "merge"
ADDRESS = "address"
REQUEST = "request"
RESPONSE = "response"
-
- MERGE = "merge"
- SUBMIT = "submit"
)
const SPIDE = "spide"
@@ -363,34 +291,25 @@ func init() {
SPIDE: {Name: "spide client.name action=raw,msg,save,cache method=GET,PUT,POST,DELETE url format=form,part,json,data,file arg run create", Help: "蜘蛛侠", Actions: ice.MergeActions(ice.Actions{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
conf := m.Confm(cli.RUNTIME, cli.CONF)
- m.Cmd(SPIDE, mdb.CREATE, ice.OPS, kit.Select("http://127.0.0.1:9020", conf[cli.CTX_OPS]))
- m.Cmd(SPIDE, mdb.CREATE, ice.DEV, kit.Select("http://contexts.woa.com:80", conf[cli.CTX_DEV]))
- m.Cmd(SPIDE, mdb.CREATE, ice.SHY, kit.Select("https://shylinux.com:443", conf[cli.CTX_SHY]))
- m.Cmd(aaa.ROLE, aaa.WHITE, aaa.VOID, SPIDE, SUBMIT)
+ m.Cmd("", mdb.CREATE, ice.OPS, kit.Select("http://127.0.0.1:9020", conf[cli.CTX_OPS]))
+ m.Cmd("", mdb.CREATE, ice.DEV, kit.Select("http://contexts.woa.com:80", conf[cli.CTX_DEV]))
+ m.Cmd("", mdb.CREATE, ice.COM, kit.Select("https://contexts.com:443", conf[cli.CTX_COM]))
+ m.Cmd("", mdb.CREATE, ice.SHY, kit.Select("https://shylinux.com:443", conf[cli.CTX_SHY]))
}},
- mdb.CREATE: {Name: "create name address", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
- _spide_create(m, m.Option(mdb.NAME), m.Option(ADDRESS))
- }},
- MERGE: {Name: "merge name path", Help: "拼接", Hand: func(m *ice.Message, arg ...string) {
- m.Echo(kit.MergeURL2(m.CmdAppend(SPIDE, arg[0], CLIENT_URL), arg[1], arg[2:]))
- }},
- SUBMIT: {Name: "submit dev pod path size cache", Help: "发布", Hand: func(m *ice.Message, arg ...string) {
- m.Cmdy(SPIDE, ice.DEV, SPIDE_RAW, m.Option(ice.DEV), SPIDE_PART, m.OptionSimple(ice.POD), nfs.PATH, ice.BIN_ICE_BIN, UPLOAD, "@"+ice.BIN_ICE_BIN)
- }},
- "client": {Hand: func(m *ice.Message, arg ...string) {
+ mdb.CREATE: {Name: "create name address", Hand: func(m *ice.Message, arg ...string) { _spide_create(m, m.Option(mdb.NAME), m.Option(ADDRESS)) }},
+ tcp.CLIENT: {Hand: func(m *ice.Message, arg ...string) {
msg := m.Cmd("", kit.Select(ice.DEV, arg, 0))
- ls := kit.Split(msg.Append("client.hostname"), ice.DF)
- m.Push(tcp.HOST, ls[0])
- m.Push(tcp.PORT, kit.Select(kit.Select("443", "80", msg.Append("client.protocol") == ice.HTTP), ls, 1))
- m.Push(tcp.HOSTNAME, msg.Append("client.hostname"))
- m.Push(tcp.PROTOCOL, msg.Append("client.protocol"))
- m.Push(DOMAIN, msg.Append("client.protocol")+"://"+msg.Append("client.hostname")+kit.Select("", arg, 1))
+ ls := kit.Split(msg.Append(CLIENT_HOSTNAME), ice.DF)
+ m.Push(tcp.HOST, ls[0]).Push(tcp.PORT, kit.Select(kit.Select("443", "80", msg.Append(CLIENT_PROTOCOL) == ice.HTTP), ls, 1))
+ m.Push(DOMAIN, msg.Append(CLIENT_PROTOCOL)+"://"+msg.Append(CLIENT_HOSTNAME)+kit.Select("", arg, 1))
+ m.Push(tcp.PROTOCOL, msg.Append(CLIENT_PROTOCOL)).Push(tcp.HOSTNAME, msg.Append(CLIENT_HOSTNAME))
}},
+ MERGE: {Hand: func(m *ice.Message, arg ...string) { m.Echo(kit.MergeURL2(m.CmdAppend("", arg[0], CLIENT_URL), arg[1], arg[2:])) }},
}, mdb.HashAction(mdb.SHORT, CLIENT_NAME, mdb.FIELD, "time,client.name,client.url", LOGHEADERS, ice.FALSE), mdb.ClearHashOnExitAction()), Hand: func(m *ice.Message, arg ...string) {
if len(arg) < 2 || arg[0] == "" || (len(arg) > 3 && arg[3] == "") {
mdb.HashSelect(m, kit.Slice(arg, 0, 1)...).Sort(CLIENT_NAME)
} else {
- _spide_list(m, arg...)
+ _spide_show(m, arg...)
}
}},
SPIDE_GET: {Name: "GET url key value run", Help: "蜘蛛侠", Hand: func(m *ice.Message, arg ...string) {
@@ -408,18 +327,10 @@ func init() {
})
}
-func SpideGet(m *ice.Message, arg ...ice.Any) ice.Any {
- return kit.UnMarshal(m.Cmdx(SPIDE_GET, arg))
-}
-func SpidePut(m *ice.Message, arg ...ice.Any) ice.Any {
- return kit.UnMarshal(m.Cmdx(SPIDE_PUT, arg))
-}
-func SpidePost(m *ice.Message, arg ...ice.Any) ice.Any {
- return kit.UnMarshal(m.Cmdx(SPIDE_POST, arg))
-}
-func SpideDelete(m *ice.Message, arg ...ice.Any) ice.Any {
- return kit.UnMarshal(m.Cmdx(SPIDE_DELETE, arg))
-}
+func SpideGet(m *ice.Message, arg ...ice.Any) ice.Any { return kit.UnMarshal(m.Cmdx(SPIDE_GET, arg)) }
+func SpidePut(m *ice.Message, arg ...ice.Any) ice.Any { return kit.UnMarshal(m.Cmdx(SPIDE_PUT, arg)) }
+func SpidePost(m *ice.Message, arg ...ice.Any) ice.Any { return kit.UnMarshal(m.Cmdx(SPIDE_POST, arg)) }
+func SpideDelete(m *ice.Message, arg ...ice.Any) ice.Any { return kit.UnMarshal(m.Cmdx(SPIDE_DELETE, arg)) }
func SpideSave(m *ice.Message, file, link string, cb func(int, int, int)) *ice.Message {
return m.Cmd("web.spide", ice.DEV, SPIDE_SAVE, file, SPIDE_GET, link, cb)
}
diff --git a/base/web/web.go b/base/web/web.go
index 859b876c..8561d9ba 100644
--- a/base/web/web.go
+++ b/base/web/web.go
@@ -39,7 +39,7 @@ func (f *Frame) Start(m *ice.Message, arg ...string) bool {
msg := m.Spawn(c)
if pf, ok := p.Server().(*Frame); ok && pf.ServeMux != nil {
route := ice.PS + c.Name + ice.PS
- msg.Log(ROUTE, "%s <= %s", p.Name, route)
+ msg.Log("route", "%s <= %s", p.Name, route)
pf.Handle(route, http.StripPrefix(path.Dir(route), f))
list[c] = path.Join(list[p], route)
}
@@ -48,7 +48,7 @@ func (f *Frame) Start(m *ice.Message, arg ...string) bool {
continue
}
func(key string, cmd *ice.Command) {
- msg.Log(ROUTE, "%s <- %s", c.Name, key)
+ msg.Log("route", "%s <- %s", c.Name, key)
f.HandleFunc(key, func(w http.ResponseWriter, r *http.Request) {
m.TryCatch(m.Spawn(key, cmd, c, w, r), true, func(msg *ice.Message) { _serve_handle(key, cmd, msg, w, r) })
})
@@ -96,7 +96,7 @@ const WEB = "web"
var Index = &ice.Context{Name: WEB, Help: "网络模块"}
func init() {
- ice.Index.Register(Index, &Frame{}, BROAD, SERVE, SPACE, DREAM, SHARE, CACHE, SPIDE, ROUTE)
+ ice.Index.Register(Index, &Frame{}, BROAD, SERVE, SPACE, DREAM, CACHE, SPIDE, SHARE)
}
func ApiAction(arg ...string) ice.Actions { return ice.Actions{kit.Select(ice.PS, arg, 0): {}} }
diff --git a/core/chat/favor.go b/core/chat/favor.go
index 44c31ef0..599c6be0 100644
--- a/core/chat/favor.go
+++ b/core/chat/favor.go
@@ -57,8 +57,7 @@ func init() {
mdb.HashCreate(m, m.OptionSimple())
}},
web.UPLOAD: {Hand: func(m *ice.Message, arg ...string) {
- msg := web.Upload(m)
- m.Cmd("", mdb.CREATE, msg.AppendSimple(mdb.TYPE, mdb.NAME, mdb.TEXT))
+ m.Cmd("", mdb.CREATE, m.OptionSimple(mdb.TYPE, mdb.NAME, mdb.TEXT))
}},
web.DOWNLOAD: {Hand: func(m *ice.Message, arg ...string) {
ctx.ProcessOpen(m, web.MergeURL2(m, web.SHARE_LOCAL+m.Option(mdb.TEXT), "filename", m.Option(mdb.NAME)))
diff --git a/core/chat/pod.go b/core/chat/pod.go
index e6a63198..bb23c45e 100644
--- a/core/chat/pod.go
+++ b/core/chat/pod.go
@@ -22,7 +22,7 @@ func init() {
web.SERVE_PARSE: {Hand: func(m *ice.Message, arg ...string) {
switch kit.Select("", arg, 0) {
case CHAT:
- for i := 1; i < len(arg)-1; i++ {
+ for i := 1; i < len(arg)-1; i += 2 {
m.Logs("refer", arg[i], arg[i+1])
m.Option(arg[i], arg[i+1])
}
diff --git a/core/chat/trans.go b/core/chat/trans.go
index b6041613..7e61824b 100644
--- a/core/chat/trans.go
+++ b/core/chat/trans.go
@@ -42,11 +42,11 @@ func init() {
}},
}, ctx.CmdAction()), Hand: func(m *ice.Message, arg ...string) {
if len(arg) == 0 {
- m.Cmdy(web.ROUTE).RenameAppend(web.ROUTE, FROM)
+ m.Cmdy(web.SPACE).RenameAppend(mdb.NAME, FROM)
return
}
if len(arg) == 1 {
- m.Cmdy(web.ROUTE).RenameAppend(web.ROUTE, TO)
+ m.Cmdy(web.SPACE).RenameAppend(mdb.NAME, TO)
return
}
ctx.DisplayLocal(m, "")
diff --git a/core/code/pprof.go b/core/code/pprof.go
index 88eb5d8c..4e7755cf 100644
--- a/core/code/pprof.go
+++ b/core/code/pprof.go
@@ -24,14 +24,13 @@ const (
const PPROF = "pprof"
func init() {
+ web.Index.MergeCommands(ice.Commands{"/debug/": {Hand: func(m *ice.Message, arg ...string) {
+ defer m.Render(ice.RENDER_VOID)
+ m.R.URL.Path = "/debug" + m.R.URL.Path
+ http.DefaultServeMux.ServeHTTP(m.W, m.R)
+ }}})
Index.MergeCommands(ice.Commands{
PPROF: {Name: "pprof zone id auto", Help: "性能分析", Actions: ice.MergeActions(ice.Actions{
- web.SERVE_REWRITE: {Hand: func(m *ice.Message, arg ...string) {
- if strings.HasPrefix(arg[1], "/debug/") {
- m.R.URL.Path = strings.Replace(m.R.URL.Path, "/debug/", "/code/", -1)
- m.Debug("rewrite %v -> %v", arg[1], m.R.URL.Path)
- }
- }},
mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) {
switch arg[0] {
case BINNARY:
@@ -58,7 +57,7 @@ func init() {
m.Cmd(cli.DAEMON, m.Configv(PPROF), "-http="+p, m.Option(BINNARY), m.Option(nfs.FILE))
m.Echo("http://%s/ui/top", p).ProcessInner()
}},
- }, mdb.ZoneAction(mdb.SHORT, mdb.ZONE, mdb.FIELD, "time,id,text,file", PPROF, kit.List(GO, "tool", PPROF)), web.ServeAction()), Hand: func(m *ice.Message, arg ...string) {
+ }, mdb.ZoneAction(mdb.SHORT, mdb.ZONE, mdb.FIELD, "time,id,text,file", PPROF, kit.List(GO, "tool", PPROF))), Hand: func(m *ice.Message, arg ...string) {
m.Fields(len(arg), "time,zone,count,binnary,service,seconds", mdb.ZoneField(m))
if mdb.ZoneSelect(m, arg...); len(arg) == 0 {
m.EchoAnchor(web.MergeLink(m, "/code/pprof/"))
@@ -71,10 +70,5 @@ func init() {
})
}
}},
- web.PP(PPROF): {Name: "/pprof/", Help: "性能分析", Hand: func(m *ice.Message, arg ...string) {
- defer m.Render(ice.RENDER_VOID)
- m.R.URL.Path = "/debug" + m.R.URL.Path
- http.DefaultServeMux.ServeHTTP(m.W, m.R)
- }},
})
}
diff --git a/core/wiki/wiki.go b/core/wiki/wiki.go
index df62ec9b..9ff70c85 100644
--- a/core/wiki/wiki.go
+++ b/core/wiki/wiki.go
@@ -48,6 +48,7 @@ func _wiki_list(m *ice.Message, arg ...string) bool {
}
m.Cmdy(nfs.DIR, kit.Slice(arg, 0, 1), kit.Dict(nfs.DIR_TYPE, nfs.CAT, nfs.DIR_REG, m.Config(lex.REGEXP)))
m.StatusTimeCount()
+ m.SortTimeR(mdb.TIME)
return true
}
ctx.DisplayLocal(m, path.Join(kit.PathName(2), kit.Keys(kit.FileName(2), ice.JS)))
@@ -60,7 +61,7 @@ func _wiki_save(m *ice.Message, name, text string, arg ...string) {
m.Cmd(nfs.SAVE, name, text, kit.Dict(nfs.DIR_ROOT, _wiki_path(m)))
}
func _wiki_upload(m *ice.Message, dir string) {
- m.Cmdy(web.CACHE, web.UPLOAD_WATCH, _wiki_path(m, dir))
+ m.Cmdy(web.CACHE, web.WATCH, m.Option(ice.MSG_UPLOAD), _wiki_path(m, dir, m.Option(mdb.NAME)))
}
func _wiki_template(m *ice.Message, name, text string, arg ...string) *ice.Message {
return _option(m, m.CommandKey(), name, strings.TrimSpace(text), arg...).RenderTemplate(m.Config(nfs.TEMPLATE), &Message{m})
@@ -81,8 +82,8 @@ func init() {
func WikiAction(dir string, ext ...string) ice.Actions {
return ice.Actions{ice.CTX_INIT: mdb.AutoConfig(nfs.PATH, dir, lex.REGEXP, kit.FileReg(ext...)),
web.UPLOAD: {Hand: func(m *ice.Message, arg ...string) { _wiki_upload(m, m.Option(nfs.PATH)) }},
- nfs.SAVE: {Name: "save path text", Hand: func(m *ice.Message, arg ...string) { _wiki_save(m, m.Option(nfs.PATH), m.Option(mdb.TEXT)) }},
- nfs.TRASH: {Hand: func(m *ice.Message, arg ...string) { nfs.Trash(m, _wiki_path(m, m.Option(nfs.PATH))) }},
+ nfs.TRASH: {Name: "trash path*", Hand: func(m *ice.Message, arg ...string) { nfs.Trash(m, _wiki_path(m, m.Option(nfs.PATH))) }},
+ nfs.SAVE: {Name: "save path* text", Hand: func(m *ice.Message, arg ...string) { _wiki_save(m, m.Option(nfs.PATH), m.Option(mdb.TEXT)) }},
mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) {
switch arg[0] {
case nfs.PATH:
diff --git a/logs.go b/logs.go
index 05a3099f..89854f15 100644
--- a/logs.go
+++ b/logs.go
@@ -44,7 +44,7 @@ func (m *Message) join(arg ...Any) (string, []Any) {
return kit.Join(list, SP), meta
}
func (m *Message) log(level string, str string, arg ...Any) *Message {
- _source := logs.FileLineMeta(logs.FileLine(3))
+ _source := logs.FileLineMeta(3)
if Info.Log != nil {
Info.Log(m, m.FormatPrefix(), level, logs.Format(str, append(arg, _source)...))
}
@@ -76,7 +76,7 @@ func (m *Message) Log(level string, str string, arg ...Any) *Message {
}
func (m *Message) Logs(level string, arg ...Any) *Message {
str, meta := m.join(arg...)
- if unicode.IsUpper([]rune(level)[0]) {
+ if len(level) > 0 && unicode.IsUpper([]rune(level)[0]) {
meta = []Any{logs.FileLineMeta("")}
}
return m.log(level, str, meta...)
@@ -99,7 +99,7 @@ func (m *Message) Info(str string, arg ...Any) *Message {
return m.log(LOG_INFO, str, arg...)
}
func (m *Message) WarnTimeNotValid(time Any, arg ...Any) bool {
- return m.Warn(kit.Format(time) < m.Time(), ErrNotValid, kit.Simple(arg), time, m.Time(), logs.FileLineMeta(logs.FileLine(2)))
+ return m.Warn(kit.Format(time) < m.Time(), ErrNotValid, kit.Simple(arg), time, m.Time(), logs.FileLineMeta(2))
}
func (m *Message) Warn(err Any, arg ...Any) bool {
switch err := err.(type) {
diff --git a/meta.go b/meta.go
index b20a89cb..051ecf7e 100644
--- a/meta.go
+++ b/meta.go
@@ -401,6 +401,12 @@ func (m *Message) Detailv(arg ...Any) []string {
func (m *Message) Options(arg ...Any) Any {
for i := 0; i < len(arg); i += 2 {
switch val := arg[i].(type) {
+ case Maps:
+ for k, v := range val {
+ m.Optionv(k, v)
+ }
+ i--
+ continue
case []string:
for i := 0; i < len(val)-1; i += 2 {
m.Optionv(val[i], val[i+1])
diff --git a/misc.go b/misc.go
index ccd2645e..31c51e3a 100644
--- a/misc.go
+++ b/misc.go
@@ -289,23 +289,25 @@ func (c *Context) _action(m *Message, cmd *Command, key string, sub string, h *A
order := false
for i, v := range h.List {
name := kit.Format(kit.Value(v, NAME))
- value := kit.Format(kit.Value(v, VALUE))
- if i == 0 && len(arg) > 0 && arg[0] != name {
- order = true
+ if i == 0 {
+ if len(arg) > 0 && arg[0] == name {
+ for i := 0; i < len(arg)-1; i += 2 {
+ if strings.HasPrefix(arg[i], PS) {
+ break
+ }
+ m.Option(arg[i], arg[i+1])
+ }
+ } else {
+ order = true
+ }
}
if order {
- value = kit.Select(value, arg, i)
- }
- if value != "" {
- m.Option(name, value)
- }
- }
- if !order {
- for i := 0; i < len(arg)-1; i += 2 {
- if strings.HasPrefix(arg[i], PS) {
- break
+ if value := kit.Select("", arg, i); value != "" {
+ m.Option(name, value)
}
- m.Option(arg[i], arg[i+1])
+ }
+ if m.Warn(m.OptionDefault(name, kit.Format(kit.Value(v, VALUE))) == "" && kit.Value(v, "need") == "must") {
+ return m
}
}
}
@@ -449,3 +451,18 @@ func SplitCmd(name string, actions Actions) (list []Any) {
}
return list
}
+func MergeHand(hand ...Handler) Handler {
+ if len(hand) == 0 {
+ return nil
+ }
+ if len(hand) == 1 {
+ return hand[0]
+ }
+ return func(m *Message, arg ...string) {
+ for _, h := range hand {
+ if h != nil {
+ h(m, arg...)
+ }
+ }
+ }
+}
diff --git a/misc/git/server.go b/misc/git/server.go
index fbfd17e2..c7dfa29c 100644
--- a/misc/git/server.go
+++ b/misc/git/server.go
@@ -111,15 +111,10 @@ func _server_reader(m *ice.Message) (io.ReadCloser, error) {
const SERVER = "server"
func init() {
+ web.Index.MergeCommands(ice.Commands{"/x/": {Hand: func(m *ice.Message, arg ...string) { m.Cmdy("web.code.git.repository", arg) }}})
Index.MergeCommands(ice.Commands{
web.WEB_LOGIN: {Hand: func(m *ice.Message, arg ...string) { m.Render(ice.RENDER_VOID) }},
- "repository": {Name: "repository", Help: "代码库", Actions: ice.MergeActions(ice.Actions{
- web.SERVE_REWRITE: {Hand: func(m *ice.Message, arg ...string) {
- if strings.HasPrefix(arg[1], "/x/") {
- _server_rewrite(m, arg[1], m.R)
- }
- }},
- }, web.ServeAction(), web.ApiAction()), Hand: func(m *ice.Message, arg ...string) {
+ "repository": {Name: "repository", Help: "代码库", Hand: func(m *ice.Message, arg ...string) {
if m.Option("go-get") == "1" { // 下载地址
p := web.MergeLink(m, "/x/"+path.Join(arg...))
m.RenderResult(kit.Format(``, "go-import", kit.Format(`%s git %s`, strings.Split(p, "://")[1], p)))
@@ -138,8 +133,7 @@ func init() {
m.Logs(mdb.CREATE, REPOS, repos)
}
case "upload-pack": // 下载代码
- if !nfs.ExistsFile(m, repos) {
- web.RenderStatus(m.W, http.StatusNotFound, kit.Format("not found: %s", arg[0]))
+ if m.Warn(!nfs.ExistsFile(m, repos), ice.ErrNotFound, arg[0]) {
return
}
}
diff --git a/render.go b/render.go
index 9885766b..f2bf497b 100644
--- a/render.go
+++ b/render.go
@@ -10,6 +10,14 @@ import (
func AddRender(key string, render func(*Message, ...Any) string) {
Info.render[key] = render
}
+func RenderAction(key ...string) Actions {
+ return Actions{CTX_INIT: {Hand: func(m *Message, arg ...string) {
+ cmd := m.CommandKey()
+ for _, key := range key {
+ AddRender(key, func(m *Message, arg ...Any) string { return m.Cmd(cmd, key, arg).Result() })
+ }
+ }}}
+}
func Render(m *Message, cmd string, args ...Any) string {
if render, ok := Info.render[cmd]; ok {
return render(m, args...)