1
0
mirror of https://shylinux.com/x/icebergs synced 2025-04-25 17:18:05 +08:00
This commit is contained in:
harveyshao 2022-12-01 23:36:23 +08:00
parent e39c6cdf8f
commit c92eda968f
27 changed files with 336 additions and 507 deletions

View File

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

View File

@ -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(

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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(`<a href="%s" download="%s">%s</a>`, 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)
}
}

View File

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

View File

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

View File

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

View File

@ -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(`<a href="%s" download="%s">%s</a>`, _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))
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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, "")

View File

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

View File

@ -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:

View File

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

View File

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

45
misc.go
View File

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

View File

@ -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(`<meta name="%s" content="%s">`, "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
}
}

View File

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