1
0
mirror of https://shylinux.com/x/icebergs synced 2025-04-29 02:29:22 +08:00
This commit is contained in:
harveyshao 2021-05-31 17:06:35 +08:00
parent 1f974390c4
commit 3b73de5368
52 changed files with 695 additions and 657 deletions

View File

@ -69,7 +69,7 @@ func init() {
m.Cmd(mdb.INSERT, TOTP, "", mdb.HASH, kit.MDB_NAME, m.Option(kit.MDB_NAME), m.Cmd(mdb.INSERT, TOTP, "", mdb.HASH, kit.MDB_NAME, m.Option(kit.MDB_NAME),
SECRET, m.Option(SECRET), PERIOD, m.Option(PERIOD), NUMBER, m.Option(NUMBER), SECRET, m.Option(SECRET), PERIOD, m.Option(PERIOD), NUMBER, m.Option(NUMBER),
) )
m.Option(ice.MSG_PROCESS, ice.PROCESS_REFRESH) m.ProcessRefresh("1ms")
}}, }},
mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) { mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(mdb.DELETE, TOTP, "", mdb.HASH, kit.MDB_NAME, m.Option(kit.MDB_NAME)) m.Cmdy(mdb.DELETE, TOTP, "", mdb.HASH, kit.MDB_NAME, m.Option(kit.MDB_NAME))

View File

@ -1,15 +1,21 @@
source aaa/aaa.shy label "base" `
source cli/cli.shy ctx cli web aaa
lex yac gdb log
tcp nfs ssh mdb
`
source ctx/ctx.shy source ctx/ctx.shy
source cli/cli.shy
source web/web.shy source web/web.shy
source aaa/aaa.shy
source gdb/gdb.shy
source lex/lex.shy source lex/lex.shy
source log/log.shy
source yac/yac.shy source yac/yac.shy
source gdb/gdb.shy
source log/log.shy
source mdb/mdb.shy source tcp/tcp.shy
source nfs/nfs.shy source nfs/nfs.shy
source ssh/ssh.shy source ssh/ssh.shy
source tcp/tcp.shy source mdb/mdb.shy

View File

@ -19,7 +19,9 @@ func NodeInfo(m *ice.Message, kind, name string) {
ice.Info.NodeType = kind ice.Info.NodeType = kind
} }
var Index = &ice.Context{Name: "cli", Help: "命令模块", const CLI = "cli"
var Index = &ice.Context{Name: CLI, Help: "命令模块",
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Load() m.Load()

View File

@ -14,18 +14,18 @@ import (
) )
var _trans_web = map[string]color.Color{ var _trans_web = map[string]color.Color{
"black": color.RGBA{0, 0, 0, 255}, BLACK: color.RGBA{0, 0, 0, DARK},
"red": color.RGBA{255, 0, 0, 255}, RED: color.RGBA{DARK, 0, 0, DARK},
"green": color.RGBA{0, 255, 0, 255}, YELLOW: color.RGBA{DARK, DARK, 0, DARK},
"yellow": color.RGBA{255, 255, 0, 255}, GREEN: color.RGBA{0, DARK, 0, DARK},
"blue": color.RGBA{0, 0, 255, 255}, CYAN: color.RGBA{0, DARK, DARK, DARK},
"magenta": color.RGBA{255, 0, 255, 255}, BLUE: color.RGBA{0, 0, DARK, DARK},
"cyan": color.RGBA{0, 255, 255, 255}, MAGENTA: color.RGBA{DARK, 0, DARK, DARK},
"white": color.RGBA{255, 255, 255, 255}, WHITE: color.RGBA{DARK, DARK, DARK, DARK},
} }
func _parse_color(str string) color.Color { func _parse_color(str string) color.Color {
if str == "random" { if str == RANDOM {
list := []string{} list := []string{}
for k := range _trans_web { for k := range _trans_web {
list = append(list, k) list = append(list, k)
@ -50,13 +50,13 @@ func _parse_color(str string) color.Color {
func _trans_cli(str string) string { func _trans_cli(str string) string {
res := 0 res := 0
r, g, b, _ := _parse_color(str).RGBA() r, g, b, _ := _parse_color(str).RGBA()
if r > 128 { if r > LIGHT {
res += 1 res += 1
} }
if g > 128 { if g > LIGHT {
res += 2 res += 2
} }
if b > 128 { if b > LIGHT {
res += 4 res += 4
} }
return kit.Format(res) return kit.Format(res)
@ -64,8 +64,8 @@ func _trans_cli(str string) string {
func _qrcode_cli(m *ice.Message, text string, arg ...string) { func _qrcode_cli(m *ice.Message, text string, arg ...string) {
qr, _ := qrcode.New(text, qrcode.Medium) qr, _ := qrcode.New(text, qrcode.Medium)
fg := _trans_cli(m.Option("fg")) fg := _trans_cli(m.Option(FG))
bg := _trans_cli(m.Option("bg")) bg := _trans_cli(m.Option(BG))
data := qr.Bitmap() data := qr.Bitmap()
for i, row := range data { for i, row := range data {
@ -84,26 +84,45 @@ func _qrcode_cli(m *ice.Message, text string, arg ...string) {
} }
func _qrcode_web(m *ice.Message, text string, arg ...string) { func _qrcode_web(m *ice.Message, text string, arg ...string) {
qr, _ := qrcode.New(text, qrcode.Medium) qr, _ := qrcode.New(text, qrcode.Medium)
qr.ForegroundColor = _parse_color(m.Option("fg")) qr.ForegroundColor = _parse_color(m.Option(FG))
qr.BackgroundColor = _parse_color(m.Option("bg")) qr.BackgroundColor = _parse_color(m.Option(BG))
if data, err := qr.PNG(kit.Int(m.Option("size"))); m.Assert(err) { if data, err := qr.PNG(kit.Int(m.Option(SIZE))); m.Assert(err) {
m.Echo(`<img src="data:image/png;base64,%s" title='%s'>`, base64.StdEncoding.EncodeToString(data), text) m.Echo(`<img src="data:image/png;base64,%s" title='%s'>`, base64.StdEncoding.EncodeToString(data), text)
} }
} }
const (
FG = "fg"
BG = "bg"
SIZE = "size"
DARK = 255
LIGHT = 127
)
const (
BLACK = "black"
RED = "red"
YELLOW = "yellow"
GREEN = "green"
CYAN = "cyan"
BLUE = "blue"
MAGENTA = "magenta"
WHITE = "white"
RANDOM = "random"
)
const QRCODE = "qrcode" const QRCODE = "qrcode"
func init() { func init() {
Index.Merge(&ice.Context{ Index.Merge(&ice.Context{
Configs: map[string]*ice.Config{ Configs: map[string]*ice.Config{
QRCODE: {Name: "qrcode", Help: "二维码", Value: kit.Data()}, QRCODE: {Name: QRCODE, Help: "二维码", Value: kit.Data()},
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
QRCODE: {Name: "qrcode text fg bg size auto", Help: "二维码", Action: map[string]*ice.Action{}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { QRCODE: {Name: "qrcode text fg bg size auto", Help: "二维码", Action: map[string]*ice.Action{}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Option("fg", kit.Select("blue", arg, 1)) m.Option(FG, kit.Select(BLUE, arg, 1))
m.Option("bg", kit.Select("white", arg, 2)) m.Option(BG, kit.Select(WHITE, arg, 2))
m.Option("size", kit.Select("240", arg, 3)) m.Option(SIZE, kit.Select("240", arg, 3))
if aaa.SessIsCli(m) { if aaa.SessIsCli(m) {
_qrcode_cli(m, arg[0]) _qrcode_cli(m, arg[0])

View File

@ -25,8 +25,8 @@ func _system_show(m *ice.Message, cmd *exec.Cmd) {
} }
} else { } else {
out := bytes.NewBuffer(make([]byte, 0, 1024)) out := bytes.NewBuffer(make([]byte, 0, ice.MOD_BUFS))
err := bytes.NewBuffer(make([]byte, 0, 1024)) err := bytes.NewBuffer(make([]byte, 0, ice.MOD_BUFS))
defer func() { defer func() {
m.Push(CMD_ERR, err.String()) m.Push(CMD_ERR, err.String())
m.Push(CMD_OUT, out.String()) m.Push(CMD_OUT, out.String())
@ -66,8 +66,10 @@ const (
DARWIN = "darwin" DARWIN = "darwin"
WINDOWS = "windows" WINDOWS = "windows"
SOURCE = "source" SOURCE = "source"
HOME = "home"
PATH = "path" USER = "USER"
HOME = "HOME"
PATH = "PATH"
) )
const SYSTEM = "system" const SYSTEM = "system"

View File

@ -36,18 +36,15 @@ func init() {
m.Cmdy(mdb.DELETE, EVENT, "", mdb.HASH, EVENT, m.Option(EVENT)) m.Cmdy(mdb.DELETE, EVENT, "", mdb.HASH, EVENT, m.Option(EVENT))
}}, }},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 { if len(arg) == 0 { // 事件列表
m.Option(mdb.FIELDS, "time,event,count") m.Option(mdb.FIELDS, "time,event,count")
m.Cmdy(mdb.SELECT, EVENT, "", mdb.HASH) m.Cmdy(mdb.SELECT, EVENT, "", mdb.HASH)
m.PushAction(ACTION, mdb.REMOVE) m.PushAction(ACTION, mdb.REMOVE)
return return
} }
m.Option(mdb.FIELDS, kit.Select("time,id,cmd", mdb.DETAIL, len(arg) > 1)) m.Fields(len(arg) == 1, "time,id,cmd")
m.Cmdy(mdb.SELECT, EVENT, kit.Keys(kit.MDB_HASH, kit.Hashs(arg[0])), mdb.LIST, kit.MDB_ID, arg[1:]) m.Cmdy(mdb.SELECT, EVENT, kit.Keys(kit.MDB_HASH, kit.Hashs(arg[0])), mdb.LIST, kit.MDB_ID, arg[1:])
if len(arg) == 1 {
m.Sort(kit.MDB_ID)
}
}}, }},
}, },
}) })

View File

@ -1,13 +1,13 @@
package gdb package gdb
import ( import (
"os"
"time"
ice "github.com/shylinux/icebergs" ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/cli" "github.com/shylinux/icebergs/base/cli"
"github.com/shylinux/icebergs/base/nfs" "github.com/shylinux/icebergs/base/nfs"
kit "github.com/shylinux/toolkits" kit "github.com/shylinux/toolkits"
"os"
"time"
) )
type Frame struct { type Frame struct {
@ -53,10 +53,11 @@ const (
STATUS = "status" STATUS = "status"
RESTART = "restart" RESTART = "restart"
RELOAD = "reload" RELOAD = "reload"
BENCH = "bench"
PPROF = "pprof" BENCH = "bench"
BEGIN = "begin" PPROF = "pprof"
END = "end" BEGIN = "begin"
END = "end"
) )
const GDB = "gdb" const GDB = "gdb"

View File

@ -1,11 +1,11 @@
package gdb package gdb
import ( import (
"strings"
ice "github.com/shylinux/icebergs" ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/mdb" "github.com/shylinux/icebergs/base/mdb"
kit "github.com/shylinux/toolkits" kit "github.com/shylinux/toolkits"
"strings"
) )
const ( const (
@ -55,7 +55,7 @@ func init() {
} }
}}, }},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Option(mdb.FIELDS, kit.Select("time,hash,status,fileline", mdb.DETAIL, len(arg) > 0)) m.Fields(len(arg) == 0, "time,hash,status,fileline")
m.Cmdy(mdb.SELECT, ROUTINE, "", mdb.HASH, kit.MDB_HASH, arg) m.Cmdy(mdb.SELECT, ROUTINE, "", mdb.HASH, kit.MDB_HASH, arg)
m.PushAction(INNER, mdb.REMOVE) m.PushAction(INNER, mdb.REMOVE)
}}, }},

View File

@ -1,12 +1,12 @@
package gdb package gdb
import ( import (
"os/signal"
"syscall"
ice "github.com/shylinux/icebergs" ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/mdb" "github.com/shylinux/icebergs/base/mdb"
kit "github.com/shylinux/toolkits" kit "github.com/shylinux/toolkits"
"os/signal"
"syscall"
) )
func _signal_listen(m *ice.Message, s int, arg ...string) { func _signal_listen(m *ice.Message, s int, arg ...string) {
@ -37,7 +37,7 @@ func init() {
)}, )},
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
SIGNAL: {Name: "signal auto listen", Help: "信号器", Action: map[string]*ice.Action{ SIGNAL: {Name: "signal signal auto listen", Help: "信号器", Action: map[string]*ice.Action{
LISTEN: {Name: "listen signal name cmd", Help: "监听", Hand: func(m *ice.Message, arg ...string) { LISTEN: {Name: "listen signal name cmd", Help: "监听", Hand: func(m *ice.Message, arg ...string) {
_signal_listen(m, kit.Int(m.Option(SIGNAL)), arg...) _signal_listen(m, kit.Int(m.Option(SIGNAL)), arg...)
}}, }},
@ -48,7 +48,7 @@ func init() {
m.Cmdy(mdb.DELETE, SIGNAL, "", mdb.HASH, SIGNAL, m.Option(SIGNAL)) m.Cmdy(mdb.DELETE, SIGNAL, "", mdb.HASH, SIGNAL, m.Option(SIGNAL))
}}, }},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Option(mdb.FIELDS, "time,signal,name,cmd") m.Fields(len(arg) == 0, "time,signal,name,cmd")
m.Cmdy(mdb.SELECT, SIGNAL, "", mdb.HASH, SIGNAL, arg) m.Cmdy(mdb.SELECT, SIGNAL, "", mdb.HASH, SIGNAL, arg)
m.PushAction(ACTION, mdb.REMOVE) m.PushAction(ACTION, mdb.REMOVE)
m.Sort(SIGNAL) m.Sort(SIGNAL)

View File

@ -1,11 +1,11 @@
package gdb package gdb
import ( import (
"time"
ice "github.com/shylinux/icebergs" ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/mdb" "github.com/shylinux/icebergs/base/mdb"
kit "github.com/shylinux/toolkits" kit "github.com/shylinux/toolkits"
"time"
) )
func _timer_create(m *ice.Message, arg ...string) { func _timer_create(m *ice.Message, arg ...string) {
@ -61,15 +61,14 @@ func init() {
}}, }},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 { if len(arg) == 0 {
m.Option(mdb.FIELDS, kit.Select("time,hash,delay,interval,order,next,cmd", mdb.DETAIL, len(arg) > 0)) m.Fields(len(arg) == 0, "time,hash,delay,interval,order,next,cmd")
m.Cmdy(mdb.SELECT, TIMER, "", mdb.HASH, kit.MDB_HASH, arg) m.Cmdy(mdb.SELECT, TIMER, "", mdb.HASH, kit.MDB_HASH, arg)
m.PushAction(mdb.REMOVE) m.PushAction(mdb.REMOVE)
return return
} }
m.Option(mdb.FIELDS, kit.Select("time,id,res", mdb.DETAIL, len(arg) > 1)) m.Fields(len(arg) == 1, "time,id,res")
m.Cmdy(mdb.SELECT, TIMER, kit.Keys(kit.MDB_HASH, arg[0]), mdb.LIST, kit.MDB_ID, arg[1:]) m.Cmdy(mdb.SELECT, TIMER, kit.Keys(kit.MDB_HASH, arg[0]), mdb.LIST, kit.MDB_ID, arg[1:])
return
}}, }},
}, },
}) })

View File

@ -1,15 +1,15 @@
package mdb package mdb
import ( import (
ice "github.com/shylinux/icebergs"
kit "github.com/shylinux/toolkits"
"encoding/csv" "encoding/csv"
"encoding/json" "encoding/json"
"os" "os"
"path" "path"
"sort" "sort"
"strings" "strings"
ice "github.com/shylinux/icebergs"
kit "github.com/shylinux/toolkits"
) )
func _file_name(m *ice.Message, arg ...string) string { func _file_name(m *ice.Message, arg ...string) string {
@ -41,7 +41,7 @@ func _hash_select(m *ice.Message, prefix, chain, field, value string) {
value = kit.MDB_RANDOMS value = kit.MDB_RANDOMS
} }
fields := _hash_fields(m) fields := _hash_fields(m)
cb := m.Optionv(SELECT_CB) cb := m.Optionv(kit.Keycb(SELECT))
m.Richs(prefix, chain, value, func(key string, val map[string]interface{}) { m.Richs(prefix, chain, value, func(key string, val map[string]interface{}) {
val = kit.GetMeta(val) val = kit.GetMeta(val)
switch cb := cb.(type) { switch cb := cb.(type) {
@ -156,7 +156,7 @@ func _list_select(m *ice.Message, prefix, chain, field, value string) {
field = "" field = ""
} }
fields := _list_fields(m) fields := _list_fields(m)
cb := m.Optionv(SELECT_CB) cb := m.Optionv(kit.Keycb(SELECT))
m.Grows(prefix, chain, kit.Select(m.Option("cache.field"), field), kit.Select(m.Option(CACHE_VALUE), value), func(index int, val map[string]interface{}) { m.Grows(prefix, chain, kit.Select(m.Option("cache.field"), field), kit.Select(m.Option(CACHE_VALUE), value), func(index int, val map[string]interface{}) {
val = kit.GetMeta(val) val = kit.GetMeta(val)
switch cb := cb.(type) { switch cb := cb.(type) {
@ -275,7 +275,7 @@ func _zone_select(m *ice.Message, prefix, chain, zone string, id string) {
} }
fields := _zone_fields(m) fields := _zone_fields(m)
cb := m.Optionv(SELECT_CB) cb := m.Optionv(kit.Keycb(SELECT))
m.Richs(prefix, chain, kit.Select(kit.MDB_FOREACH, zone), func(key string, val map[string]interface{}) { m.Richs(prefix, chain, kit.Select(kit.MDB_FOREACH, zone), func(key string, val map[string]interface{}) {
val = kit.GetMeta(val) val = kit.GetMeta(val)
if zone == "" { if zone == "" {
@ -405,16 +405,10 @@ const (
DELETE = "delete" DELETE = "delete"
REMOVE = "remove" REMOVE = "remove"
SELECT_CB = "select.cb"
EXPORT = "export" EXPORT = "export"
IMPORT = "import" IMPORT = "import"
PRUNES = "prunes" PRUNES = "prunes"
INPUTS = "inputs" INPUTS = "inputs"
SCRIPT = "script"
COMMIT = "commit"
SOURCE = "source"
UPLOAD = "upload"
) )
const ( const (
CACHE_LIMIT = "cache.limit" CACHE_LIMIT = "cache.limit"

View File

@ -1,10 +1,10 @@
package mdb package mdb
import ( import (
"strings"
ice "github.com/shylinux/icebergs" ice "github.com/shylinux/icebergs"
kit "github.com/shylinux/toolkits" kit "github.com/shylinux/toolkits"
"strings"
) )
const SEARCH = "search" const SEARCH = "search"

View File

@ -182,13 +182,8 @@ func init() {
nil, kit.Split("time,size,type,path")) nil, kit.Split("time,size,type,path"))
}}, }},
mdb.UPLOAD: {Name: "upload", Help: "上传", Hand: func(m *ice.Message, arg ...string) { "upload": {Name: "upload", Help: "上传", Hand: func(m *ice.Message, arg ...string) {
up := kit.Simple(m.Optionv(ice.MSG_UPLOAD)) m.Upload(m.Option(kit.MDB_PATH))
if p := path.Join(m.Option(kit.MDB_PATH), up[1]); m.Option(ice.MSG_USERPOD) == "" {
m.Cmdy("web.cache", "watch", up[0], p)
} else {
m.Cmdy("web.spide", "dev", "save", p, "GET", kit.MergeURL2(m.Option(ice.MSG_USERWEB), "/share/cache/"+up[0]))
}
}}, }},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 { if len(arg) == 0 {

View File

@ -56,7 +56,7 @@ func init() {
m.Toast("已经是最后一页啦!") m.Toast("已经是最后一页啦!")
} }
m.Process("_rewrite", "offend", offend) m.ProcessRewrite("offend", offend)
}}, }},
"next": {Name: "next", Help: "下一页", Hand: func(m *ice.Message, arg ...string) { "next": {Name: "next", Help: "下一页", Hand: func(m *ice.Message, arg ...string) {
offend := kit.Int(kit.Select("0", arg, 3)) - kit.Int(kit.Select("10", arg, 2)) offend := kit.Int(kit.Select("0", arg, 3)) - kit.Int(kit.Select("10", arg, 2))
@ -64,7 +64,7 @@ func init() {
offend = 0 offend = 0
m.Toast("已经是第一页啦!") m.Toast("已经是第一页啦!")
} }
m.Process("_rewrite", "offend", offend) m.ProcessRewrite("offend", offend)
}}, }},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Option(mdb.FIELDS, kit.Select("time,hash,count,name,file", kit.Select("time,id,file,text", mdb.DETAIL, len(arg) > 1 && arg[1] != ""), len(arg) > 0)) m.Option(mdb.FIELDS, kit.Select("time,hash,count,name,file", kit.Select("time,id,file,text", mdb.DETAIL, len(arg) > 1 && arg[1] != ""), len(arg) > 0))

View File

@ -29,6 +29,9 @@ func _trash_create(m *ice.Message, name string) {
} }
} }
} }
func _trash_prunes(m *ice.Message) {
m.Cmd(mdb.DELETE, TRASH, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH))
}
const TRASH = "trash" const TRASH = "trash"
@ -40,16 +43,23 @@ func init() {
)}, )},
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
TRASH: {Name: "trash file auto", Help: "回收站", Action: map[string]*ice.Action{ TRASH: {Name: "trash file auto prunes", Help: "回收站", Action: map[string]*ice.Action{
"recover": {Name: "recover", Help: "恢复", Hand: func(m *ice.Message, arg ...string) { "recover": {Name: "recover", Help: "恢复", Hand: func(m *ice.Message, arg ...string) {
os.Rename(m.Option(kit.MDB_FILE), m.Option(kit.MDB_FROM)) os.Rename(m.Option(kit.MDB_FILE), m.Option(kit.MDB_FROM))
m.Cmd(mdb.DELETE, TRASH, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH)) m.Cmd(mdb.DELETE, TRASH, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH))
}}, }},
mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
os.Remove(m.Option(kit.MDB_FILE))
m.Cmd(mdb.DELETE, TRASH, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH))
}},
mdb.PRUNES: {Name: "prunes", Help: "清理", Hand: func(m *ice.Message, arg ...string) {
_trash_prunes(m)
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 { if len(arg) == 0 {
m.Option(mdb.FIELDS, "time,hash,file,from") m.Option(mdb.FIELDS, "time,hash,file,from")
m.Cmdy(mdb.SELECT, TRASH, "", mdb.HASH) m.Cmdy(mdb.SELECT, TRASH, "", mdb.HASH)
m.PushAction("recover") m.PushAction("recover", mdb.REMOVE)
return return
} }
_trash_create(m, arg[0]) _trash_create(m, arg[0])

View File

@ -12,6 +12,7 @@ import (
ice "github.com/shylinux/icebergs" ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/aaa" "github.com/shylinux/icebergs/base/aaa"
"github.com/shylinux/icebergs/base/cli"
"github.com/shylinux/icebergs/base/mdb" "github.com/shylinux/icebergs/base/mdb"
"github.com/shylinux/icebergs/base/nfs" "github.com/shylinux/icebergs/base/nfs"
"github.com/shylinux/icebergs/base/tcp" "github.com/shylinux/icebergs/base/tcp"
@ -111,7 +112,7 @@ func _ssh_conn(m *ice.Message, conn net.Conn, username, hostport string) *ssh.Cl
})) }))
methods = append(methods, ssh.PublicKeysCallback(func() ([]ssh.Signer, error) { methods = append(methods, ssh.PublicKeysCallback(func() ([]ssh.Signer, error) {
key, err := ssh.ParsePrivateKey([]byte(m.Cmdx(nfs.CAT, path.Join(os.Getenv("HOME"), m.Option("private"))))) key, err := ssh.ParsePrivateKey([]byte(m.Cmdx(nfs.CAT, path.Join(os.Getenv(cli.HOME), m.Option("private")))))
return []ssh.Signer{key}, err return []ssh.Signer{key}, err
})) }))
methods = append(methods, ssh.PasswordCallback(func() (string, error) { methods = append(methods, ssh.PasswordCallback(func() (string, error) {
@ -127,6 +128,76 @@ func _ssh_conn(m *ice.Message, conn net.Conn, username, hostport string) *ssh.Cl
return ssh.NewClient(c, chans, reqs) return ssh.NewClient(c, chans, reqs)
} }
func _ssh_open(m *ice.Message, arg ...string) {
var client *ssh.Client
w, h, _ := terminal.GetSize(int(os.Stdin.Fd()))
_ssh_password(m, m.Option("authfile"))
p := path.Join(os.Getenv("HOME"), ".ssh/", fmt.Sprintf("%s@%s", m.Option("username"), m.Option("host")))
if _, e := os.Stat(p); e == nil {
if c, e := net.Dial("unix", p); e == nil {
pr, pw := _ssh_stream(m, os.Stdin)
defer _ssh_store(os.Stdout)()
defer _ssh_store(os.Stdin)()
c.Write([]byte(fmt.Sprintf("height:%d,width:%d\n", h, w)))
m.Go(func() { io.Copy(c, pr) })
_ssh_init(m, pw)
m.Echo("logout\n")
io.Copy(os.Stdout, c)
return
} else {
os.Remove(p)
}
}
if l, e := net.Listen("unix", p); m.Assert(e) {
defer func() { os.Remove(p) }()
defer l.Close()
m.Go(func() {
for {
if c, e := l.Accept(); e == nil {
buf := make([]byte, 1024)
if n, e := c.Read(buf); m.Assert(e) {
fmt.Sscanf(string(buf[:n]), "height:%d,width:%d", &h, &w)
}
session := _ssh_session(m, client, w, h, c, c, c)
func(session *ssh.Session) {
m.Go(func() {
defer c.Close()
session.Wait()
})
}(session)
} else {
break
}
}
})
}
m.Option(kit.Keycb(tcp.DIAL), func(c net.Conn) {
client = _ssh_conn(m, c, m.Option(aaa.USERNAME), m.Option(tcp.HOST)+":"+m.Option(tcp.PORT))
pr, pw := _ssh_stream(m, os.Stdin)
defer _ssh_store(os.Stdout)()
defer _ssh_store(os.Stdin)()
session := _ssh_session(m, client, w, h, pr, os.Stdout, os.Stderr)
_ssh_init(m, pw)
_ssh_tick(m, pw)
session.Wait()
})
m.Cmdy(tcp.CLIENT, tcp.DIAL, kit.MDB_TYPE, "ssh", kit.MDB_NAME, m.Option(tcp.HOST),
tcp.PORT, m.Option(tcp.PORT), tcp.HOST, m.Option(tcp.HOST), arg)
m.Echo("exit %s\n", m.Option(tcp.HOST))
}
const CONNECT = "connect" const CONNECT = "connect"
func init() { func init() {
@ -137,25 +208,34 @@ func init() {
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
CONNECT: {Name: "connect hash auto dial prunes", Help: "连接", Action: map[string]*ice.Action{ CONNECT: {Name: "connect hash auto dial prunes", Help: "连接", Action: map[string]*ice.Action{
tcp.DIAL: {Name: "dial username=shy host=shylinux.com port=22 private=.ssh/id_rsa", Help: "添加", Hand: func(m *ice.Message, arg ...string) { tcp.DIAL: {Name: "dial username=shy host=shylinux.com port=22 private=.ssh/id_rsa", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
m.Option(tcp.DIAL_CB, func(c net.Conn) { m.Option(kit.Keycb(tcp.DIAL), func(c net.Conn) {
client := _ssh_conn(m, c, kit.Select("shy", m.Option(aaa.USERNAME)), client := _ssh_conn(m, c, kit.Select("shy", m.Option(aaa.USERNAME)),
kit.Select("shylinux.com", m.Option(tcp.HOST))+":"+kit.Select("22", m.Option(tcp.PORT)), kit.Select("shylinux.com", m.Option(tcp.HOST))+":"+kit.Select("22", m.Option(tcp.PORT)),
) )
h := m.Rich(CONNECT, "", kit.Dict( h := m.Rich(CONNECT, "", kit.Dict(
aaa.USERNAME, m.Option(aaa.USERNAME), aaa.USERNAME, m.Option(aaa.USERNAME),
tcp.HOST, m.Option(tcp.HOST), tcp.HOST, m.Option(tcp.HOST), tcp.PORT, m.Option(tcp.PORT),
tcp.PORT, m.Option(tcp.PORT), kit.MDB_STATUS, tcp.OPEN, CONNECT, client,
kit.MDB_STATUS, tcp.OPEN,
CONNECT, client,
)) ))
m.Cmd(CONNECT, SESSION, kit.MDB_HASH, h) m.Cmd(CONNECT, SESSION, kit.MDB_HASH, h)
m.Echo(h) m.Echo(h)
}) })
m.Cmds(tcp.CLIENT, tcp.DIAL, kit.MDB_TYPE, SSH, kit.MDB_NAME, m.Option(aaa.USERNAME), tcp.PORT, m.Option(tcp.PORT), tcp.HOST, m.Option(tcp.HOST)) m.Cmds(tcp.CLIENT, tcp.DIAL, kit.MDB_TYPE, SSH, kit.MDB_NAME, m.Option(aaa.USERNAME),
m.Sleep("100ms") tcp.PORT, m.Option(tcp.PORT), tcp.HOST, m.Option(tcp.HOST))
}}, }},
tcp.OPEN: {Name: "open authfile= username=shy password= verfiy= host=shylinux.com port=22 private=.ssh/id_rsa tick=", Help: "终端", Hand: func(m *ice.Message, arg ...string) {
_ssh_open(m, arg...)
}},
mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(mdb.DELETE, CONNECT, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH))
}},
mdb.PRUNES: {Name: "prunes", Help: "清理", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(mdb.PRUNES, CONNECT, "", mdb.HASH, kit.MDB_STATUS, tcp.ERROR)
m.Cmdy(mdb.PRUNES, CONNECT, "", mdb.HASH, kit.MDB_STATUS, tcp.CLOSE)
}},
SESSION: {Name: "session hash", Help: "会话", Hand: func(m *ice.Message, arg ...string) { SESSION: {Name: "session hash", Help: "会话", Hand: func(m *ice.Message, arg ...string) {
m.Richs(CONNECT, "", m.Option(kit.MDB_HASH), func(key string, value map[string]interface{}) { m.Richs(CONNECT, "", m.Option(kit.MDB_HASH), func(key string, value map[string]interface{}) {
client, ok := value[CONNECT].(*ssh.Client) client, ok := value[CONNECT].(*ssh.Client)
@ -169,84 +249,8 @@ func init() {
} }
}) })
}}, }},
"open": {Name: "open authfile= username=shy password= verfiy= host=shylinux.com port=22 private=.ssh/id_rsa tick=", Help: "终端", Hand: func(m *ice.Message, arg ...string) {
var client *ssh.Client
w, h, _ := terminal.GetSize(int(os.Stdin.Fd()))
_ssh_password(m, m.Option("authfile"))
p := path.Join(os.Getenv("HOME"), ".ssh/", fmt.Sprintf("%s@%s", m.Option("username"), m.Option("host")))
if _, e := os.Stat(p); e == nil {
if c, e := net.Dial("unix", p); e == nil {
pr, pw := _ssh_stream(m, os.Stdin)
defer _ssh_store(os.Stdout)()
defer _ssh_store(os.Stdin)()
c.Write([]byte(fmt.Sprintf("height:%d,width:%d\n", h, w)))
m.Go(func() { io.Copy(c, pr) })
_ssh_init(m, pw)
m.Echo("logout\n")
io.Copy(os.Stdout, c)
return
} else {
os.Remove(p)
}
}
if l, e := net.Listen("unix", p); m.Assert(e) {
defer func() { os.Remove(p) }()
defer l.Close()
m.Go(func() {
for {
if c, e := l.Accept(); e == nil {
buf := make([]byte, 1024)
if n, e := c.Read(buf); m.Assert(e) {
fmt.Sscanf(string(buf[:n]), "height:%d,width:%d", &h, &w)
}
session := _ssh_session(m, client, w, h, c, c, c)
func(session *ssh.Session) {
m.Go(func() {
defer c.Close()
session.Wait()
})
}(session)
} else {
break
}
}
})
}
m.Option(tcp.DIAL_CB, func(c net.Conn) {
client = _ssh_conn(m, c, m.Option(aaa.USERNAME), m.Option(tcp.HOST)+":"+m.Option(tcp.PORT))
pr, pw := _ssh_stream(m, os.Stdin)
defer _ssh_store(os.Stdout)()
defer _ssh_store(os.Stdin)()
session := _ssh_session(m, client, w, h, pr, os.Stdout, os.Stderr)
_ssh_init(m, pw)
_ssh_tick(m, pw)
session.Wait()
})
m.Cmdy(tcp.CLIENT, tcp.DIAL, kit.MDB_TYPE, "ssh", kit.MDB_NAME, m.Option(tcp.HOST),
tcp.PORT, m.Option(tcp.PORT), tcp.HOST, m.Option(tcp.HOST), arg)
m.Echo("exit %s\n", m.Option(tcp.HOST))
}},
mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(mdb.DELETE, CONNECT, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH))
}},
mdb.PRUNES: {Name: "prunes", Help: "清理", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(mdb.PRUNES, CONNECT, "", mdb.HASH, kit.MDB_STATUS, tcp.CLOSE)
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Option(mdb.FIELDS, kit.Select("time,hash,status,username,host,port", mdb.DETAIL, len(arg) > 0)) m.Fields(len(arg) == 0, "time,hash,status,username,host,port")
if m.Cmdy(mdb.SELECT, CONNECT, "", mdb.HASH, kit.MDB_HASH, arg); len(arg) == 0 { if m.Cmdy(mdb.SELECT, CONNECT, "", mdb.HASH, kit.MDB_HASH, arg); len(arg) == 0 {
m.Table(func(index int, value map[string]string, head []string) { m.Table(func(index int, value map[string]string, head []string) {
m.PushButton(kit.Select("", mdb.REMOVE, value[kit.MDB_STATUS] == tcp.CLOSE)) m.PushButton(kit.Select("", mdb.REMOVE, value[kit.MDB_STATUS] == tcp.CLOSE))

View File

@ -1,12 +1,6 @@
package ssh package ssh
import ( import (
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/aaa"
"github.com/shylinux/icebergs/base/mdb"
"github.com/shylinux/icebergs/base/nfs"
kit "github.com/shylinux/toolkits"
"bufio" "bufio"
"bytes" "bytes"
"fmt" "fmt"
@ -15,6 +9,12 @@ import (
"path" "path"
"strings" "strings"
"time" "time"
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/aaa"
"github.com/shylinux/icebergs/base/mdb"
"github.com/shylinux/icebergs/base/nfs"
kit "github.com/shylinux/toolkits"
) )
func Render(msg *ice.Message, cmd string, args ...interface{}) { func Render(msg *ice.Message, cmd string, args ...interface{}) {

View File

@ -113,7 +113,7 @@ func init() {
m.Cmd(SERVICE, mdb.IMPORT, kit.MDB_FILE, m.Option("auth")) m.Cmd(SERVICE, mdb.IMPORT, kit.MDB_FILE, m.Option("auth"))
} }
m.Option(tcp.LISTEN_CB, func(c net.Conn) { m.Go(func() { _ssh_accept(m, kit.Hashs(m.Option(tcp.PORT)), c) }) }) m.Option(kit.Keycb(tcp.LISTEN), func(c net.Conn) { m.Go(func() { _ssh_accept(m, kit.Hashs(m.Option(tcp.PORT)), c) }) })
m.Go(func() { m.Go(func() {
m.Cmdy(tcp.SERVER, tcp.LISTEN, kit.MDB_TYPE, SSH, kit.MDB_NAME, tcp.PORT, tcp.PORT, m.Option(tcp.PORT)) m.Cmdy(tcp.SERVER, tcp.LISTEN, kit.MDB_TYPE, SSH, kit.MDB_NAME, tcp.PORT, tcp.PORT, m.Option(tcp.PORT))
}) })

View File

@ -1,13 +1,13 @@
package ssh package ssh
import ( import (
ice "github.com/shylinux/icebergs"
"golang.org/x/crypto/ssh"
"encoding/binary" "encoding/binary"
"net" "net"
"syscall" "syscall"
"unsafe" "unsafe"
ice "github.com/shylinux/icebergs"
"golang.org/x/crypto/ssh"
) )
func _ssh_size(fd uintptr, b []byte) { func _ssh_size(fd uintptr, b []byte) {

View File

@ -1,12 +1,6 @@
package ssh package ssh
import ( import (
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/mdb"
"github.com/shylinux/icebergs/base/tcp"
kit "github.com/shylinux/toolkits"
"golang.org/x/crypto/ssh"
"encoding/binary" "encoding/binary"
"github.com/kr/pty" "github.com/kr/pty"
"io" "io"
@ -14,6 +8,12 @@ import (
"os" "os"
"syscall" "syscall"
"unsafe" "unsafe"
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/mdb"
"github.com/shylinux/icebergs/base/tcp"
kit "github.com/shylinux/toolkits"
"golang.org/x/crypto/ssh"
) )
func _ssh_size(fd uintptr, b []byte) { func _ssh_size(fd uintptr, b []byte) {

View File

@ -1,9 +1,10 @@
package ssh package ssh
import ( import (
"net"
ice "github.com/shylinux/icebergs" ice "github.com/shylinux/icebergs"
"golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh"
"net"
) )
func _ssh_size(fd uintptr, b []byte) { func _ssh_size(fd uintptr, b []byte) {

View File

@ -1,11 +1,11 @@
package tcp package tcp
import ( import (
"net"
ice "github.com/shylinux/icebergs" ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/mdb" "github.com/shylinux/icebergs/base/mdb"
kit "github.com/shylinux/toolkits" kit "github.com/shylinux/toolkits"
"net"
) )
type Stat struct { type Stat struct {
@ -23,32 +23,27 @@ type Conn struct {
func (c *Conn) Read(b []byte) (int, error) { func (c *Conn) Read(b []byte) (int, error) {
n, e := c.Conn.Read(b) n, e := c.Conn.Read(b)
c.s.nr += n c.s.nr += n
// c.m.Conf(CLIENT, kit.Keys(kit.MDB_HASH, c.h, kit.MDB_META, "nread"), c.s.nr)
return n, e return n, e
} }
func (c *Conn) Write(b []byte) (int, error) { func (c *Conn) Write(b []byte) (int, error) {
n, e := c.Conn.Write(b) n, e := c.Conn.Write(b)
c.s.nw += n c.s.nw += n
// c.m.Conf(CLIENT, kit.Keys(kit.MDB_HASH, c.h, kit.MDB_META, "nwrite"), c.s.nw)
return n, e return n, e
} }
func (c *Conn) Close() error { func (c *Conn) Close() error {
// c.m.Cmd(mdb.MODIFY, CLIENT, "", mdb.HASH, kit.MDB_HASH, c.h, kit.MDB_STATUS, CLOSE, "nread", c.s.nr, "nwrite", c.s.nw) c.m.Cmd(mdb.MODIFY, CLIENT, "", mdb.HASH, kit.MDB_HASH, c.h, kit.MDB_STATUS, CLOSE, "nread", c.s.nr, "nwrite", c.s.nw)
return c.Conn.Close() return c.Conn.Close()
} }
const ( const (
SOCKET = "socket"
OPEN = "open" OPEN = "open"
START = "start"
ERROR = "error"
CLOSE = "close" CLOSE = "close"
ERROR = "error"
START = "start"
STOP = "stop" STOP = "stop"
) )
const ( const (
DIAL_CB = "dial.cb" DIAL = "dial"
DIAL = "dial"
) )
const CLIENT = "client" const CLIENT = "client"
@ -62,17 +57,16 @@ func init() {
CLIENT: {Name: "client hash auto prunes", Help: "客户端", Action: map[string]*ice.Action{ CLIENT: {Name: "client hash auto prunes", Help: "客户端", Action: map[string]*ice.Action{
DIAL: {Name: "dial type name port=9010 host=", Help: "连接", Hand: func(m *ice.Message, arg ...string) { DIAL: {Name: "dial type name port=9010 host=", Help: "连接", Hand: func(m *ice.Message, arg ...string) {
c, e := net.Dial(TCP, m.Option(HOST)+":"+m.Option(PORT)) c, e := net.Dial(TCP, m.Option(HOST)+":"+m.Option(PORT))
// h := m.Cmdx(mdb.INSERT, CLIENT, "", mdb.HASH, PORT, m.Option(PORT), HOST, m.Option(HOST), h := m.Cmdx(mdb.INSERT, CLIENT, "", mdb.HASH, PORT, m.Option(PORT), HOST, m.Option(HOST),
// kit.MDB_TYPE, m.Option(kit.MDB_TYPE), kit.MDB_NAME, m.Option(kit.MDB_NAME), kit.MDB_TYPE, m.Option(kit.MDB_TYPE), kit.MDB_NAME, m.Option(kit.MDB_NAME),
// kit.MDB_STATUS, kit.Select(ERROR, OPEN, e == nil), kit.MDB_ERROR, kit.Format(e)) kit.MDB_STATUS, kit.Select(ERROR, OPEN, e == nil), kit.MDB_ERROR, kit.Format(e))
//
// c = &Conn{m: m, h: h, s: &Stat{}, Conn: c} c = &Conn{m: m, h: h, s: &Stat{}, Conn: c}
c = &Conn{m: m, s: &Stat{}, Conn: c}
if e == nil { if e == nil {
defer c.Close() defer c.Close()
} }
switch cb := m.Optionv(DIAL_CB).(type) { switch cb := m.Optionv(kit.Keycb(DIAL)).(type) {
case func(net.Conn, error): case func(net.Conn, error):
cb(c, e) cb(c, e)
case func(net.Conn): case func(net.Conn):
@ -98,7 +92,7 @@ func init() {
m.Cmdy(mdb.PRUNES, CLIENT, "", mdb.HASH, kit.MDB_STATUS, CLOSE) m.Cmdy(mdb.PRUNES, CLIENT, "", mdb.HASH, kit.MDB_STATUS, CLOSE)
}}, }},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Option(mdb.FIELDS, kit.Select("time,hash,status,type,name,host,port,error,nread,nwrite", mdb.DETAIL, len(arg) > 0)) m.Fields(len(arg) == 0, "time,hash,status,type,name,host,port,error,nread,nwrite")
if m.Cmdy(mdb.SELECT, CLIENT, "", mdb.HASH, kit.MDB_HASH, arg); len(arg) == 0 { if m.Cmdy(mdb.SELECT, CLIENT, "", mdb.HASH, kit.MDB_HASH, arg); len(arg) == 0 {
m.Table(func(index int, value map[string]string, head []string) { m.Table(func(index int, value map[string]string, head []string) {
m.PushButton(kit.Select("", mdb.REMOVE, value[kit.MDB_STATUS] == OPEN)) m.PushButton(kit.Select("", mdb.REMOVE, value[kit.MDB_STATUS] == OPEN))

View File

@ -1,18 +1,18 @@
package tcp package tcp
import ( import (
"net"
"strings"
ice "github.com/shylinux/icebergs" ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/aaa" "github.com/shylinux/icebergs/base/aaa"
kit "github.com/shylinux/toolkits" kit "github.com/shylinux/toolkits"
"net"
"strings"
) )
func _host_list(m *ice.Message, ifname string) { func _host_list(m *ice.Message, name string) {
if ifs, e := net.Interfaces(); m.Assert(e) { if ifs, e := net.Interfaces(); m.Assert(e) {
for _, v := range ifs { for _, v := range ifs {
if ifname != "" && !strings.Contains(v.Name, ifname) { if name != "" && !strings.Contains(v.Name, name) {
continue continue
} }
if len(v.HardwareAddr.String()) == 0 { if len(v.HardwareAddr.String()) == 0 {
@ -26,22 +26,22 @@ func _host_list(m *ice.Message, ifname string) {
continue continue
} }
m.Push("index", v.Index) m.Push(kit.MDB_INDEX, v.Index)
m.Push("name", v.Name) m.Push(kit.MDB_NAME, v.Name)
m.Push("ip", ip[0]) m.Push(IP, ip[0])
m.Push("mask", ip[1]) m.Push(MASK, ip[1])
m.Push("hard", v.HardwareAddr.String()) m.Push(HARD, v.HardwareAddr.String())
} }
} }
} }
} }
if len(m.Appendv("ip")) == 0 { if len(m.Appendv(IP)) == 0 {
m.Push("index", -1) m.Push(kit.MDB_INDEX, -1)
m.Push("name", "local") m.Push(kit.MDB_NAME, LOCALHOST)
m.Push("ip", "127.0.0.1") m.Push(IP, "127.0.0.1")
m.Push("mask", "255.0.0.0") m.Push(MASK, "255.0.0.0")
m.Push("hard", "") m.Push(HARD, "")
} }
} }
@ -49,10 +49,10 @@ func _islocalhost(m *ice.Message, ip string) (ok bool) {
if ip == "::1" || strings.HasPrefix(ip, "127.") { if ip == "::1" || strings.HasPrefix(ip, "127.") {
return true return true
} }
if m.Richs(HOST, kit.Keys("meta.black"), ip, nil) != nil { if m.Richs(HOST, kit.Keym(aaa.BLACK), ip, nil) != nil {
return false return false
} }
if m.Richs(HOST, kit.Keys("meta.white"), ip, nil) != nil { if m.Richs(HOST, kit.Keym(aaa.WHITE), ip, nil) != nil {
m.Log_AUTH(aaa.WHITE, ip) m.Log_AUTH(aaa.WHITE, ip)
return true return true
} }
@ -66,7 +66,10 @@ const (
PROTOCOL = "protocol" PROTOCOL = "protocol"
LOCALHOST = "localhost" LOCALHOST = "localhost"
IP = "ip"
HARD = "hard"
MASK = "mask"
IP = "ip"
) )
const HOST = "host" const HOST = "host"
@ -81,10 +84,10 @@ func init() {
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
HOST: {Name: "host name auto", Help: "主机", Action: map[string]*ice.Action{ HOST: {Name: "host name auto", Help: "主机", Action: map[string]*ice.Action{
aaa.BLACK: {Name: "black", Help: "黑名单", Hand: func(m *ice.Message, arg ...string) { aaa.BLACK: {Name: "black", Help: "黑名单", Hand: func(m *ice.Message, arg ...string) {
m.Rich(HOST, kit.Keys("meta.black"), kit.Dict(kit.MDB_TEXT, arg[0])) m.Rich(HOST, kit.Keym(aaa.BLACK), kit.Dict(kit.MDB_TEXT, arg[0]))
}}, }},
aaa.WHITE: {Name: "white", Help: "白名单", Hand: func(m *ice.Message, arg ...string) { aaa.WHITE: {Name: "white", Help: "白名单", Hand: func(m *ice.Message, arg ...string) {
m.Rich(HOST, kit.Keys("meta.white"), kit.Dict(kit.MDB_TEXT, arg[0])) m.Rich(HOST, kit.Keym(aaa.WHITE), kit.Dict(kit.MDB_TEXT, arg[0]))
}}, }},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
_host_list(m, kit.Select("", arg, 0)) _host_list(m, kit.Select("", arg, 0))

View File

@ -1,15 +1,15 @@
package tcp package tcp
import ( import (
"net"
"os"
"path"
ice "github.com/shylinux/icebergs" ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/aaa" "github.com/shylinux/icebergs/base/aaa"
"github.com/shylinux/icebergs/base/cli" "github.com/shylinux/icebergs/base/cli"
"github.com/shylinux/icebergs/base/nfs" "github.com/shylinux/icebergs/base/nfs"
kit "github.com/shylinux/toolkits" kit "github.com/shylinux/toolkits"
"net"
"os"
"path"
) )
func _port_list(m *ice.Message, port string, dir string) { func _port_list(m *ice.Message, port string, dir string) {
@ -20,15 +20,15 @@ func _port_list(m *ice.Message, port string, dir string) {
m.Cmd(nfs.DIR, "./").Table(func(index int, value map[string]string, head []string) { m.Cmd(nfs.DIR, "./").Table(func(index int, value map[string]string, head []string) {
m.Push(kit.MDB_TIME, value[kit.MDB_TIME]) m.Push(kit.MDB_TIME, value[kit.MDB_TIME])
m.Push(kit.MDB_SIZE, value[kit.MDB_SIZE])
m.Push(PORT, path.Base(value[kit.MDB_PATH])) m.Push(PORT, path.Base(value[kit.MDB_PATH]))
m.Push(kit.MDB_SIZE, value[kit.MDB_SIZE])
}) })
} }
func _port_right(m *ice.Message, begin string) string { func _port_right(m *ice.Message, begin string) string {
current := kit.Int(kit.Select(m.Conf(PORT, "meta.current"), begin)) current := kit.Int(kit.Select(m.Conf(PORT, kit.Keym(CURRENT)), begin))
end := kit.Int(m.Conf(PORT, "meta.end")) end := kit.Int(m.Conf(PORT, kit.Keym(END)))
if current >= end { if current >= end {
current = kit.Int(m.Conf(PORT, "meta.begin")) current = kit.Int(m.Conf(PORT, kit.Keym(BEGIN)))
} }
for i := current; i < end; i++ { for i := current; i < end; i++ {
@ -39,14 +39,17 @@ func _port_right(m *ice.Message, begin string) string {
} }
m.Log_SELECT(PORT, i) m.Log_SELECT(PORT, i)
m.Conf(PORT, "meta.current", i) m.Conf(PORT, kit.Keym(CURRENT), i)
return kit.Format("%d", i) return kit.Format("%d", i)
} }
return "" return ""
} }
const ( const (
RANDOM = "random" RANDOM = "random"
CURRENT = "current"
BEGIN = "begin"
END = "end"
) )
const PORT = "port" const PORT = "port"
@ -54,7 +57,7 @@ func init() {
Index.Merge(&ice.Context{ Index.Merge(&ice.Context{
Configs: map[string]*ice.Config{ Configs: map[string]*ice.Config{
PORT: {Name: PORT, Help: "端口", Value: kit.Data( PORT: {Name: PORT, Help: "端口", Value: kit.Data(
"begin", 10000, "current", 10000, "end", 20000, BEGIN, 10000, CURRENT, 10000, END, 20000,
)}, )},
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{

View File

@ -1,12 +1,11 @@
package tcp package tcp
import ( import (
"net"
ice "github.com/shylinux/icebergs" ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/mdb" "github.com/shylinux/icebergs/base/mdb"
kit "github.com/shylinux/toolkits" kit "github.com/shylinux/toolkits"
"net"
// "strings"
) )
type Listener struct { type Listener struct {
@ -20,17 +19,6 @@ type Listener struct {
func (l Listener) Accept() (net.Conn, error) { func (l Listener) Accept() (net.Conn, error) {
c, e := l.Listener.Accept() c, e := l.Listener.Accept()
l.s.nc += 1 l.s.nc += 1
l.m.Conf(SERVER, kit.Keys(kit.MDB_HASH, l.h, kit.MDB_META, "nconn"), l.s.nc)
// ls := strings.Split(c.RemoteAddr().String(), ":")
// if strings.Contains(c.RemoteAddr().String(), "[") {
// ls = strings.Split(strings.TrimPrefix(c.RemoteAddr().String(), "["), "]:")
// }
// h := l.m.Cmdx(mdb.INSERT, CLIENT, "", mdb.HASH, HOST, ls[0], PORT, ls[1],
// kit.MDB_TYPE, l.m.Option(kit.MDB_TYPE), kit.MDB_NAME, l.m.Option(kit.MDB_NAME),
// kit.MDB_STATUS, kit.Select(ERROR, OPEN, e == nil), kit.MDB_ERROR, kit.Format(e))
// return &Conn{m: l.m, h: h, s: &Stat{}, Conn: c}, e
return &Conn{m: l.m, h: "", s: &Stat{}, Conn: c}, e return &Conn{m: l.m, h: "", s: &Stat{}, Conn: c}, e
} }
func (l Listener) Close() error { func (l Listener) Close() error {
@ -39,8 +27,7 @@ func (l Listener) Close() error {
} }
const ( const (
LISTEN_CB = "listen.cb" LISTEN = "listen"
LISTEN = "listen"
) )
const SERVER = "server" const SERVER = "server"
@ -54,16 +41,15 @@ func init() {
SERVER: {Name: "server hash auto prunes", Help: "服务器", Action: map[string]*ice.Action{ SERVER: {Name: "server hash auto prunes", Help: "服务器", Action: map[string]*ice.Action{
LISTEN: {Name: "LISTEN type name port=9010 host=", Help: "监听", Hand: func(m *ice.Message, arg ...string) { LISTEN: {Name: "LISTEN type name port=9010 host=", Help: "监听", Hand: func(m *ice.Message, arg ...string) {
l, e := net.Listen(TCP, m.Option(HOST)+":"+m.Option(PORT)) l, e := net.Listen(TCP, m.Option(HOST)+":"+m.Option(PORT))
// h := m.Cmdx(mdb.INSERT, SERVER, "", mdb.HASH, arg, h := m.Cmdx(mdb.INSERT, SERVER, "", mdb.HASH, arg,
// kit.MDB_STATUS, kit.Select(ERROR, OPEN, e == nil), kit.MDB_ERROR, kit.Format(e)) kit.MDB_STATUS, kit.Select(ERROR, OPEN, e == nil), kit.MDB_ERROR, kit.Format(e))
//
// l = &Listener{m: m, h: h, s: &Stat{}, Listener: l} l = &Listener{m: m, h: h, s: &Stat{}, Listener: l}
l = &Listener{m: m, s: &Stat{}, Listener: l}
if e == nil { if e == nil {
defer l.Close() defer l.Close()
} }
switch cb := m.Optionv(LISTEN_CB).(type) { switch cb := m.Optionv(kit.Keycb(LISTEN)).(type) {
case func(net.Listener, error): case func(net.Listener, error):
cb(l, e) cb(l, e)
case func(net.Listener): case func(net.Listener):
@ -108,7 +94,7 @@ func init() {
m.Cmdy(mdb.PRUNES, SERVER, "", mdb.HASH, kit.MDB_STATUS, CLOSE) m.Cmdy(mdb.PRUNES, SERVER, "", mdb.HASH, kit.MDB_STATUS, CLOSE)
}}, }},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Option(mdb.FIELDS, kit.Select("time,hash,status,type,name,host,port,error,nconn", mdb.DETAIL, len(arg) > 0)) m.Fields(len(arg) == 0, "time,hash,status,type,name,host,port,error,nconn")
if m.Cmdy(mdb.SELECT, SERVER, "", mdb.HASH, kit.MDB_HASH, arg); len(arg) == 0 { if m.Cmdy(mdb.SELECT, SERVER, "", mdb.HASH, kit.MDB_HASH, arg); len(arg) == 0 {
m.Table(func(index int, value map[string]string, head []string) { m.Table(func(index int, value map[string]string, head []string) {
m.PushButton(kit.Select("", mdb.REMOVE, value[kit.MDB_STATUS] == CLOSE)) m.PushButton(kit.Select("", mdb.REMOVE, value[kit.MDB_STATUS] == CLOSE))

View File

@ -13,17 +13,17 @@ var Index = &ice.Context{Name: TCP, Help: "通信模块",
ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Load() m.Load()
m.Cmd(HOST).Table(func(index int, value map[string]string, head []string) { m.Cmd(HOST).Table(func(index int, value map[string]string, head []string) {
m.Cmd(HOST, aaa.WHITE, value["ip"]) m.Cmd(HOST, aaa.WHITE, value[IP])
}) })
}}, }},
ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Richs(CLIENT, "", kit.MDB_FOREACH, func(key string, value map[string]interface{}) { m.Richs(CLIENT, "", kit.MDB_FOREACH, func(key string, value map[string]interface{}) {
kit.Value(value, "meta.status", CLOSE) kit.Value(value, kit.Keym(kit.MDB_STATUS), CLOSE)
}) })
m.Richs(SERVER, "", kit.MDB_FOREACH, func(key string, value map[string]interface{}) { m.Richs(SERVER, "", kit.MDB_FOREACH, func(key string, value map[string]interface{}) {
kit.Value(value, "meta.status", CLOSE) kit.Value(value, kit.Keym(kit.MDB_STATUS), CLOSE)
}) })
m.Save() m.Save(PORT)
}}, }},
}, },
} }

View File

@ -1,15 +1,15 @@
package web package web
import ( import (
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/mdb"
"github.com/shylinux/icebergs/base/nfs"
kit "github.com/shylinux/toolkits"
"io" "io"
"net/http" "net/http"
"os" "os"
"path" "path"
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/mdb"
"github.com/shylinux/icebergs/base/nfs"
kit "github.com/shylinux/toolkits"
) )
func _cache_name(m *ice.Message, h string) string { func _cache_name(m *ice.Message, h string) string {
@ -62,7 +62,6 @@ func _cache_catch(m *ice.Message, name string) (file, size string) {
} }
return "", "0" 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) (kind, name, file, size string) {
if buf, h, e := r.FormFile(UPLOAD); e == nil { if buf, h, e := r.FormFile(UPLOAD); e == nil {
defer buf.Close() defer buf.Close()
@ -84,7 +83,7 @@ func _cache_upload(m *ice.Message, r *http.Request) (kind, name, file, size stri
func _cache_download(m *ice.Message, r *http.Response) (file, size string) { func _cache_download(m *ice.Message, r *http.Response) (file, size string) {
defer r.Body.Close() defer r.Body.Close()
if f, p, e := kit.Create(path.Join("var/tmp", kit.Hashs("uniq"))); m.Assert(e) { if f, p, e := kit.Create(path.Join(ice.VAR_TMP, kit.Hashs("uniq"))); m.Assert(e) {
step, total := 0, kit.Int(kit.Select("1", r.Header.Get(ContentLength))) step, total := 0, kit.Int(kit.Select("1", r.Header.Get(ContentLength)))
size, buf := 0, make([]byte, ice.MOD_BUFS) size, buf := 0, make([]byte, ice.MOD_BUFS)
@ -94,7 +93,7 @@ func _cache_download(m *ice.Message, r *http.Response) (file, size string) {
f.Write(buf[0:n]) f.Write(buf[0:n])
s := size * 100 / total s := size * 100 / total
switch cb := m.Optionv(DOWNLOAD_CB).(type) { switch cb := m.Optionv(kit.Keycb(DOWNLOAD)).(type) {
case func(int, int): case func(int, int):
cb(size, total) cb(size, total)
case []string: case []string:
@ -129,13 +128,11 @@ func _cache_download(m *ice.Message, r *http.Response) (file, size string) {
} }
const ( const (
WATCH = "watch" WATCH = "watch"
CATCH = "catch" CATCH = "catch"
WRITE = "write" WRITE = "write"
UPLOAD = "upload"
UPLOAD = "upload" DOWNLOAD = "download"
DOWNLOAD = "download"
DOWNLOAD_CB = "download.cb"
) )
const CACHE = "cache" const CACHE = "cache"
@ -143,8 +140,8 @@ func init() {
Index.Merge(&ice.Context{ Index.Merge(&ice.Context{
Configs: map[string]*ice.Config{ Configs: map[string]*ice.Config{
CACHE: {Name: CACHE, Help: "缓存池", Value: kit.Data( CACHE: {Name: CACHE, Help: "缓存池", Value: kit.Data(
kit.MDB_SHORT, kit.MDB_TEXT, kit.MDB_PATH, "var/file", kit.MDB_SHORT, kit.MDB_TEXT, kit.MDB_PATH, ice.VAR_FILE,
kit.MDB_STORE, "var/data", kit.MDB_FSIZE, "200000", kit.MDB_STORE, ice.VAR_DATA, kit.MDB_FSIZE, "200000",
kit.MDB_LIMIT, "50", kit.MDB_LEAST, "30", kit.MDB_LIMIT, "50", kit.MDB_LEAST, "30",
)}, )},
}, },
@ -171,21 +168,21 @@ func init() {
} }
}}, }},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Option(mdb.FIELDS, kit.Select("time,hash,size,type,name,text", mdb.DETAIL, len(arg) > 0)) m.Fields(len(arg) == 0, "time,hash,size,type,name,text")
m.Cmdy(mdb.SELECT, CACHE, "", mdb.HASH, kit.MDB_HASH, arg) if m.Cmdy(mdb.SELECT, CACHE, "", mdb.HASH, kit.MDB_HASH, arg); len(arg) == 0 {
return
}
if len(arg) > 0 { if m.Append(kit.MDB_FILE) == "" {
if m.Append(kit.MDB_FILE) == "" { m.Push(kit.MDB_LINK, m.Append(kit.MDB_TEXT))
m.Push(kit.MDB_LINK, m.Append(kit.MDB_TEXT)) } else {
} else { m.PushAnchor(DOWNLOAD, kit.MergeURL2(m.Option(ice.MSG_USERWEB), "/share/cache/"+arg[0]))
m.PushAnchor(DOWNLOAD, kit.MergeURL2(m.Option(ice.MSG_USERWEB), "/share/cache/"+arg[0]))
}
} }
}}, }},
"/cache/": {Name: "/cache/", Help: "缓存池", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { "/cache/": {Name: "/cache/", Help: "缓存池", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Richs(CACHE, nil, arg[0], func(key string, value map[string]interface{}) { m.Richs(CACHE, nil, arg[0], func(key string, value map[string]interface{}) {
if value[kit.MDB_FILE] == nil { if kit.Format(value[kit.MDB_FILE]) == "" {
m.Render(ice.RENDER_DOWNLOAD, value[kit.MDB_FILE]) m.Render(ice.RENDER_DOWNLOAD, value[kit.MDB_FILE])
} else { } else {
m.Render(ice.RENDER_RESULT, value[kit.MDB_TEXT]) m.Render(ice.RENDER_RESULT, value[kit.MDB_TEXT])

View File

@ -1,6 +1,11 @@
package web package web
import ( import (
"io/ioutil"
"os"
"path"
"strings"
ice "github.com/shylinux/icebergs" ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/cli" "github.com/shylinux/icebergs/base/cli"
"github.com/shylinux/icebergs/base/gdb" "github.com/shylinux/icebergs/base/gdb"
@ -8,11 +13,6 @@ import (
"github.com/shylinux/icebergs/base/nfs" "github.com/shylinux/icebergs/base/nfs"
"github.com/shylinux/icebergs/base/tcp" "github.com/shylinux/icebergs/base/tcp"
kit "github.com/shylinux/toolkits" kit "github.com/shylinux/toolkits"
"io/ioutil"
"os"
"path"
"strings"
) )
func _dream_list(m *ice.Message) { func _dream_list(m *ice.Message) {
@ -73,9 +73,8 @@ func _dream_show(m *ice.Message, name string) {
if m.Richs(SPACE, nil, name, nil) == nil { if m.Richs(SPACE, nil, name, nil) == nil {
m.Option(cli.CMD_DIR, p) m.Option(cli.CMD_DIR, p)
m.Optionv(cli.CMD_ENV, kit.Simple( m.Optionv(cli.CMD_ENV, kit.Simple(
// "ctx_dev", m.Conf(cli.RUNTIME, "conf.ctx_dev"),
"ctx_dev", "http://:"+m.Cmd(SERVE).Append(tcp.PORT), "ctx_dev", "http://:"+m.Cmd(SERVE).Append(tcp.PORT),
"PATH", kit.Path(path.Join(p, kit.SSH_BIN))+":"+kit.Path(kit.SSH_BIN)+":"+os.Getenv("PATH"), cli.PATH, kit.Path(path.Join(p, kit.SSH_BIN))+":"+kit.Path(kit.SSH_BIN)+":"+os.Getenv(cli.PATH),
"USER", ice.Info.UserName, m.Confv(DREAM, kit.Keym(kit.SSH_ENV)), "USER", ice.Info.UserName, m.Confv(DREAM, kit.Keym(kit.SSH_ENV)),
)) ))
// 启动任务 // 启动任务
@ -111,7 +110,7 @@ func init() {
}}, }},
mdb.CREATE: {Name: "create main=src/main.go@key name=hi@key from=usr/icebergs/misc/bash/bash.go@key", Help: "添加", Hand: func(m *ice.Message, arg ...string) { mdb.CREATE: {Name: "create main=src/main.go@key name=hi@key from=usr/icebergs/misc/bash/bash.go@key", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(SPACE, m.Option(ROUTE), "web.code.autogen", mdb.CREATE, arg) m.Cmdy(SPACE, m.Option(ROUTE), "web.code.autogen", mdb.CREATE, arg)
m.Option(ice.MSG_PROCESS, ice.PROCESS_INNER) m.ProcessInner()
}}, }},
tcp.START: {Name: "start name repos", Help: "启动", Hand: func(m *ice.Message, arg ...string) { tcp.START: {Name: "start name repos", Help: "启动", Hand: func(m *ice.Message, arg ...string) {
if m.Option(kit.MDB_NAME) == SPIDE_SELF { if m.Option(kit.MDB_NAME) == SPIDE_SELF {

View File

@ -51,14 +51,14 @@ func _route_list(m *ice.Message) {
m.Cmd(tcp.HOST).Table(func(index int, value map[string]string, head []string) { m.Cmd(tcp.HOST).Table(func(index int, value map[string]string, head []string) {
m.Push(kit.MDB_TYPE, MYSELF) m.Push(kit.MDB_TYPE, MYSELF)
m.Push(kit.SSH_ROUTE, ice.Info.NodeName) m.Push(kit.SSH_ROUTE, ice.Info.NodeName)
m.PushAnchor(value["ip"], kit.Format("%s://%s:%s", u.Scheme, value["ip"], u.Port())) m.PushAnchor(value[tcp.IP], kit.Format("%s://%s:%s", u.Scheme, value[tcp.IP], u.Port()))
m.PushButton(tcp.START) m.PushButton(tcp.START)
}) })
// 本机信息 // 本机信息
m.Push(kit.MDB_TYPE, MYSELF) m.Push(kit.MDB_TYPE, MYSELF)
m.Push(kit.SSH_ROUTE, ice.Info.NodeName) m.Push(kit.SSH_ROUTE, ice.Info.NodeName)
m.PushAnchor("localhost", kit.Format("%s://%s:%s", u.Scheme, "localhost", u.Port())) m.PushAnchor(tcp.LOCALHOST, kit.Format("%s://%s:%s", u.Scheme, tcp.LOCALHOST, u.Port()))
m.PushButton(tcp.START) m.PushButton(tcp.START)
m.Sort(kit.SSH_ROUTE) m.Sort(kit.SSH_ROUTE)
@ -108,11 +108,11 @@ func init() {
mdb.CREATE: {Name: "create main=src/main.go@key name=hi@key from=usr/icebergs/misc/bash/bash.go@key", Help: "添加", Hand: func(m *ice.Message, arg ...string) { mdb.CREATE: {Name: "create main=src/main.go@key name=hi@key from=usr/icebergs/misc/bash/bash.go@key", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(SPACE, m.Option(ROUTE), "web.code.autogen", mdb.CREATE, arg) m.Cmdy(SPACE, m.Option(ROUTE), "web.code.autogen", mdb.CREATE, arg)
m.Option(ice.MSG_PROCESS, ice.PROCESS_INNER) m.ProcessInner()
}}, }},
tcp.START: {Name: "start name repos template", Help: "启动", Hand: func(m *ice.Message, arg ...string) { tcp.START: {Name: "start name repos template", Help: "启动", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(SPACE, m.Option(ROUTE), DREAM, tcp.START, arg) m.Cmdy(SPACE, m.Option(ROUTE), DREAM, tcp.START, arg)
m.Option(ice.MSG_PROCESS, ice.PROCESS_INNER) m.ProcessInner()
}}, }},
ctx.COMMAND: {Name: "command", Help: "命令", Hand: func(m *ice.Message, arg ...string) { ctx.COMMAND: {Name: "command", Help: "命令", Hand: func(m *ice.Message, arg ...string) {
m.Debug(m.Option(ROUTE)) m.Debug(m.Option(ROUTE))

View File

@ -35,7 +35,7 @@ func _serve_main(m *ice.Message, w http.ResponseWriter, r *http.Request) bool {
m.Info("").Info("%s %s %s", r.Header.Get(ice.MSG_USERIP), r.Method, r.URL) m.Info("").Info("%s %s %s", r.Header.Get(ice.MSG_USERIP), r.Method, r.URL)
// 参数日志 // 参数日志
if m.Conf(SERVE, kit.Keym("logheaders")) == "true" { if m.Conf(SERVE, kit.Keym(LOGHEADERS)) == "true" {
for k, v := range r.Header { for k, v := range r.Header {
m.Info("%s: %v", k, kit.Format(v)) m.Info("%s: %v", k, kit.Format(v))
} }
@ -56,7 +56,7 @@ func _serve_main(m *ice.Message, w http.ResponseWriter, r *http.Request) bool {
} }
// 主页接口 // 主页接口
if r.Method == "GET" && r.URL.Path == "/" { if r.Method == SPIDE_GET && r.URL.Path == "/" {
msg := m.Spawn() msg := m.Spawn()
msg.W, msg.R = w, r msg.W, msg.R = w, r
repos := kit.Select(ice.INTSHELL, ice.VOLCANOS, strings.Contains(r.Header.Get("User-Agent"), "Mozilla/5.0")) repos := kit.Select(ice.INTSHELL, ice.VOLCANOS, strings.Contains(r.Header.Get("User-Agent"), "Mozilla/5.0"))
@ -211,14 +211,14 @@ func init() {
LOGIN, true, SPACE, true, SHARE, true, LOGIN, true, SPACE, true, SHARE, true,
ice.VOLCANOS, true, ice.INTSHELL, true, ice.VOLCANOS, true, ice.INTSHELL, true,
ice.REQUIRE, true, ice.PUBLISH, true, ice.REQUIRE, true, ice.PUBLISH, true,
), "logheaders", false, ), LOGHEADERS, false,
kit.SSH_STATIC, kit.Dict("/", ice.USR_VOLCANOS), kit.SSH_STATIC, kit.Dict("/", ice.USR_VOLCANOS),
ice.VOLCANOS, kit.Dict(kit.MDB_PATH, ice.USR_VOLCANOS, kit.SSH_INDEX, "page/index.html", ice.VOLCANOS, kit.Dict(kit.MDB_PATH, ice.USR_VOLCANOS, kit.SSH_INDEX, "page/index.html",
kit.SSH_REPOS, "https://github.com/shylinux/volcanos", kit.SSH_BRANCH, kit.SSH_MASTER, kit.SSH_REPOS, "https://github.com/shylinux/volcanos", kit.SSH_BRANCH, kit.SSH_MASTER,
), ice.PUBLISH, ice.USR_PUBLISH, ), ice.PUBLISH, ice.USR_PUBLISH,
ice.INTSHELL, kit.Dict(kit.MDB_PATH, ice.USR_INTSHELL, kit.SSH_INDEX, "index.sh", ice.INTSHELL, kit.Dict(kit.MDB_PATH, ice.USR_INTSHELL, kit.SSH_INDEX, ice.INDEX_SH,
kit.SSH_REPOS, "https://github.com/shylinux/intshell", kit.SSH_BRANCH, kit.SSH_MASTER, kit.SSH_REPOS, "https://github.com/shylinux/intshell", kit.SSH_BRANCH, kit.SSH_MASTER,
), ice.REQUIRE, ".ish/pluged", ), ice.REQUIRE, ".ish/pluged",
)}, )},

View File

@ -1,17 +1,17 @@
package web package web
import ( import (
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/aaa"
"github.com/shylinux/icebergs/base/mdb"
"github.com/shylinux/icebergs/base/tcp"
kit "github.com/shylinux/toolkits"
"net/http" "net/http"
"os" "os"
"path" "path"
"strings" "strings"
"time" "time"
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/aaa"
"github.com/shylinux/icebergs/base/mdb"
"github.com/shylinux/icebergs/base/tcp"
kit "github.com/shylinux/toolkits"
) )
func _share_domain(m *ice.Message) string { func _share_domain(m *ice.Message) string {
@ -47,7 +47,7 @@ func _share_local(m *ice.Message, arg ...string) {
} }
if m.Option(kit.SSH_POD) != "" { // 远程文件 if m.Option(kit.SSH_POD) != "" { // 远程文件
pp := path.Join("var/proxy", m.Option(kit.SSH_POD), p) pp := path.Join(ice.VAR_PROXY, m.Option(kit.SSH_POD), p)
cache := time.Now().Add(-time.Hour * 240000) cache := time.Now().Add(-time.Hour * 240000)
if s, e := os.Stat(pp); e == nil { if s, e := os.Stat(pp); e == nil {
cache = s.ModTime() cache = s.ModTime()
@ -61,7 +61,7 @@ func _share_local(m *ice.Message, arg ...string) {
} }
} }
if p == "usr/publish/order.js" { if p == path.Join(ice.USR_PUBLISH, ice.ORDER_JS) {
if _, e := os.Stat(p); os.IsNotExist(e) { if _, e := os.Stat(p); os.IsNotExist(e) {
m.Render(ice.RENDER_RESULT, "") m.Render(ice.RENDER_RESULT, "")
return return
@ -72,16 +72,16 @@ func _share_local(m *ice.Message, arg ...string) {
func _share_proxy(m *ice.Message, arg ...string) { func _share_proxy(m *ice.Message, arg ...string) {
switch m.R.Method { switch m.R.Method {
case http.MethodGet: // 下发文件 case http.MethodGet: // 下发文件
m.Render(ice.RENDER_DOWNLOAD, path.Join("var/proxy", path.Join(m.Option(kit.SSH_POD), m.Option(kit.MDB_PATH), m.Option(kit.MDB_NAME)))) m.Render(ice.RENDER_DOWNLOAD, path.Join(ice.VAR_PROXY, path.Join(m.Option(kit.SSH_POD), m.Option(kit.MDB_PATH), m.Option(kit.MDB_NAME))))
case http.MethodPost: // 上传文件 case http.MethodPost: // 上传文件
m.Cmdy(CACHE, UPLOAD) m.Cmdy(CACHE, UPLOAD)
m.Cmdy(CACHE, WATCH, m.Option("data"), path.Join("var/proxy", m.Option(kit.SSH_POD), m.Option(kit.MDB_PATH))) m.Cmdy(CACHE, WATCH, m.Option(kit.MDB_DATA), path.Join(ice.VAR_PROXY, m.Option(kit.SSH_POD), m.Option(kit.MDB_PATH)))
m.Render(ice.RENDER_RESULT, m.Option(kit.MDB_PATH)) m.Render(ice.RENDER_RESULT, m.Option(kit.MDB_PATH))
} }
} }
func _share_repos(m *ice.Message, repos string, arg ...string) { func _share_repos(m *ice.Message, repos string, arg ...string) {
prefix := kit.Path(m.Conf(SERVE, "meta.require")) prefix := kit.Path(m.Conf(SERVE, kit.Keym(ice.REQUIRE)))
if _, e := os.Stat(path.Join(prefix, repos)); e != nil { if _, e := os.Stat(path.Join(prefix, repos)); e != nil {
m.Cmd("web.code.git.repos", mdb.CREATE, kit.SSH_REPOS, "https://"+repos, kit.MDB_PATH, path.Join(prefix, repos)) m.Cmd("web.code.git.repos", mdb.CREATE, kit.SSH_REPOS, "https://"+repos, kit.MDB_PATH, path.Join(prefix, repos))
} }
@ -104,7 +104,7 @@ func init() {
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
SHARE: {Name: "share hash auto", Help: "共享链", Action: map[string]*ice.Action{ SHARE: {Name: "share hash auto", Help: "共享链", Action: map[string]*ice.Action{
mdb.CREATE: {Name: "create type name text", Help: "创建", Hand: func(m *ice.Message, arg ...string) { mdb.CREATE: {Name: "create type name text", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(mdb.INSERT, SHARE, "", mdb.HASH, kit.MDB_TIME, m.Time(m.Conf(SHARE, "meta.expire")), m.Cmdy(mdb.INSERT, SHARE, "", mdb.HASH, kit.MDB_TIME, m.Time(m.Conf(SHARE, kit.Keym(kit.MDB_EXPIRE))),
aaa.USERROLE, m.Option(ice.MSG_USERROLE), aaa.USERNAME, m.Option(ice.MSG_USERNAME), aaa.USERROLE, m.Option(ice.MSG_USERROLE), aaa.USERNAME, m.Option(ice.MSG_USERNAME),
RIVER, m.Option(ice.MSG_RIVER), STORM, m.Option(ice.MSG_STORM), arg) RIVER, m.Option(ice.MSG_RIVER), STORM, m.Option(ice.MSG_STORM), arg)
}}, }},

View File

@ -43,13 +43,13 @@ func _space_dial(m *ice.Message, dev, name string, arg ...string) {
m.Go(func() { m.Go(func() {
for i := 0; i >= 0 && i < kit.Int(redial["c"]); i++ { for i := 0; i >= 0 && i < kit.Int(redial["c"]); i++ {
msg := m.Spawn() msg := m.Spawn()
msg.Option(tcp.DIAL_CB, func(s net.Conn, e error) { msg.Option(kit.Keycb(tcp.DIAL), func(s net.Conn, e error) {
if msg.Warn(e != nil, e) { if msg.Warn(e != nil, e) {
return return
} }
if s, _, e := websocket.NewClient(s, u, nil, kit.Int(redial["r"]), kit.Int(redial["w"])); !msg.Warn(e != nil, e) { if s, _, e := websocket.NewClient(s, u, nil, kit.Int(redial["r"]), kit.Int(redial["w"])); !msg.Warn(e != nil, e) {
msg.Rich(SPACE, nil, kit.Dict(tcp.SOCKET, s, kit.MDB_TYPE, MASTER, kit.MDB_NAME, dev, kit.MDB_TEXT, host)) msg.Rich(SPACE, nil, kit.Dict(SOCKET, s, kit.MDB_TYPE, MASTER, kit.MDB_NAME, dev, kit.MDB_TEXT, host))
msg.Log_CREATE(SPACE, dev, "retry", i, "uri", uri) msg.Log_CREATE(SPACE, dev, "retry", i, "uri", uri)
// 连接成功 // 连接成功
@ -78,7 +78,7 @@ func _space_send(m *ice.Message, space string, arg ...string) {
target := kit.Split(space, ".", ".") target := kit.Split(space, ".", ".")
m.Warn(m.Richs(SPACE, nil, target[0], func(key string, value map[string]interface{}) { m.Warn(m.Richs(SPACE, nil, target[0], func(key string, value map[string]interface{}) {
if socket, ok := value[tcp.SOCKET].(*websocket.Conn); !m.Warn(!ok, ice.ErrNotFound, tcp.SOCKET) { if socket, ok := value[SOCKET].(*websocket.Conn); !m.Warn(!ok, ice.ErrNotFound, SOCKET) {
// 复制选项 // 复制选项
for _, k := range kit.Simple(m.Optionv(ice.MSG_OPTS)) { for _, k := range kit.Simple(m.Optionv(ice.MSG_OPTS)) {
@ -148,7 +148,7 @@ func _space_handle(m *ice.Message, safe bool, send map[string]*ice.Message, c *w
} }
} else if msg.Richs(SPACE, nil, target[0], func(key string, value map[string]interface{}) { } else if msg.Richs(SPACE, nil, target[0], func(key string, value map[string]interface{}) {
if s, ok := value[tcp.SOCKET].(*websocket.Conn); ok { if s, ok := value[SOCKET].(*websocket.Conn); ok {
socket, source, target = s, source, target[1:] socket, source, target = s, source, target[1:]
_space_echo(msg, source, target, socket, kit.Select("", target)) _space_echo(msg, source, target, socket, kit.Select("", target))
return // 转发报文 return // 转发报文
@ -188,9 +188,6 @@ func _space_search(m *ice.Message, kind, name, text string, arg ...string) {
switch value[kit.MDB_TYPE] { switch value[kit.MDB_TYPE] {
case MASTER: case MASTER:
m.Debug("what %v", m.Cmd(SPIDE, value[kit.MDB_NAME]).Append("client.url"))
m.Debug("what %v", m.Cmd(SPIDE, value[kit.MDB_NAME]))
m.PushSearch(kit.SSH_CMD, SPACE, kit.MDB_TYPE, value[kit.MDB_TYPE], kit.MDB_NAME, value[kit.MDB_NAME], m.PushSearch(kit.SSH_CMD, SPACE, kit.MDB_TYPE, value[kit.MDB_TYPE], kit.MDB_NAME, value[kit.MDB_NAME],
kit.MDB_TEXT, m.Cmd(SPIDE, value[kit.MDB_NAME], ice.OptionFields("client.url")).Append("client.url"), value) kit.MDB_TEXT, m.Cmd(SPIDE, value[kit.MDB_NAME], ice.OptionFields("client.url")).Append("client.url"), value)
@ -223,6 +220,8 @@ const (
const ( const (
SPACE_START = "space.start" SPACE_START = "space.start"
SPACE_STOP = "space.stop" SPACE_STOP = "space.stop"
SOCKET = "socket"
) )
const SPACE = "space" const SPACE = "space"
@ -260,7 +259,7 @@ func init() {
river := m.Option("river") river := m.Option("river")
// 添加节点 // 添加节点
h := m.Rich(SPACE, nil, kit.Dict(tcp.SOCKET, s, "share", share, "river", river, h := m.Rich(SPACE, nil, kit.Dict(SOCKET, s, "share", share, "river", river,
kit.MDB_TYPE, kind, kit.MDB_NAME, name, kit.MDB_TEXT, s.RemoteAddr().String(), kit.MDB_TYPE, kind, kit.MDB_NAME, name, kit.MDB_TEXT, s.RemoteAddr().String(),
)) ))

View File

@ -14,7 +14,6 @@ import (
"time" "time"
ice "github.com/shylinux/icebergs" ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/cli"
"github.com/shylinux/icebergs/base/mdb" "github.com/shylinux/icebergs/base/mdb"
kit "github.com/shylinux/toolkits" kit "github.com/shylinux/toolkits"
) )
@ -27,17 +26,243 @@ func _spide_create(m *ice.Message, name, address string) {
}) == nil { }) == nil {
dir, file := path.Split(uri.EscapedPath()) dir, file := path.Split(uri.EscapedPath())
m.Echo(m.Rich(SPIDE, nil, kit.Dict( m.Echo(m.Rich(SPIDE, nil, kit.Dict(
"cookie", kit.Dict(), "header", kit.Dict(), "client", kit.Dict( SPIDE_COOKIE, kit.Dict(), SPIDE_HEADER, kit.Dict(), SPIDE_CLIENT, kit.Dict(
"name", name, "url", address, "method", SPIDE_POST, "name", name, "url", address, "method", SPIDE_POST,
"protocol", uri.Scheme, "hostname", uri.Host, "protocol", uri.Scheme, "hostname", uri.Host,
"path", dir, "file", file, "query", uri.RawQuery, "path", dir, "file", file, "query", uri.RawQuery,
"timeout", "600s", "logheaders", false, "timeout", "600s", LOGHEADERS, false,
), ),
))) )))
} }
m.Log_CREATE(SPIDE, name, ADDRESS, address) m.Log_CREATE(SPIDE, name, ADDRESS, address)
} }
} }
func _spide_show(m *ice.Message, arg ...string) {
m.Richs(SPIDE, nil, arg[0], func(key string, value map[string]interface{}) {
// 缓存方式
cache, save := "", ""
switch arg[1] {
case SPIDE_RAW:
cache, arg = arg[1], arg[1:]
case SPIDE_MSG:
cache, arg = arg[1], arg[1:]
case SPIDE_SAVE:
cache, save, arg = arg[1], arg[2], arg[2:]
case SPIDE_CACHE:
cache, arg = arg[1], arg[1:]
}
// 请求方法
client := value[SPIDE_CLIENT].(map[string]interface{})
method := kit.Select(SPIDE_POST, client[SPIDE_METHOD])
switch arg = arg[1:]; arg[0] {
case SPIDE_GET:
method, arg = SPIDE_GET, arg[1:]
case SPIDE_PUT:
method, arg = SPIDE_PUT, arg[1:]
case SPIDE_POST:
method, arg = SPIDE_POST, arg[1:]
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(kit.Format(client["url"]), uri, arg), body)
if m.Warn(e != nil, ice.ErrNotFound, e) {
return
}
// 请求配置
_spide_head(m, req, head, value)
// 发送请求
res, e := _spide_send(m, req, kit.Format(client["timeout"]))
if m.Warn(e != nil, ice.ErrNotFound, e) {
return
}
// 检查结果
defer res.Body.Close()
m.Cost(kit.MDB_STATUS, res.Status, kit.MDB_SIZE, res.Header.Get(ContentLength), kit.MDB_TYPE, res.Header.Get(ContentType))
// 缓存配置
for _, v := range res.Cookies() {
kit.Value(value, kit.Keys(SPIDE_COOKIE, v.Name), v.Value)
m.Log(ice.LOG_IMPORT, "%s: %s", v.Name, v.Value)
}
// 错误信息
if m.Warn(res.StatusCode != http.StatusOK, res.Status) {
switch m.Set(ice.MSG_RESULT); res.StatusCode {
case http.StatusNotFound:
return
default:
}
}
// 解析结果
_spide_save(m, cache, save, uri, res)
})
}
func _spide_body(m *ice.Message, method string, arg ...string) (io.Reader, map[string]string, []string) {
head := map[string]string{}
body, ok := m.Optionv(SPIDE_BODY).(io.Reader)
if !ok && len(arg) > 0 && method != SPIDE_GET {
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
case SPIDE_PART:
body, head[ContentType] = _spide_part(m, arg...)
case SPIDE_DATA:
body, arg = bytes.NewBufferString(arg[1]), arg[2:]
case SPIDE_FILE:
if f, e := os.Open(arg[1]); m.Assert(e) {
defer f.Close()
body, arg = f, arg[2:]
}
case SPIDE_JSON:
arg = arg[1:]
fallthrough
default:
data := map[string]interface{}{}
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.Log_EXPORT(SPIDE_JSON, kit.Format(data))
}
arg = arg[:0]
} else {
body = bytes.NewBuffer([]byte{})
}
return body, head, arg
}
func _spide_part(m *ice.Message, arg ...string) (io.Reader, string) {
buf := &bytes.Buffer{}
mp := multipart.NewWriter(buf)
defer mp.Close()
cache := time.Now().Add(-time.Hour * 240000)
for i := 1; i < len(arg)-1; i += 2 {
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], "@") {
if s, e := os.Stat(arg[i+1][1:]); e == nil {
if s.ModTime().Before(cache) {
break
}
}
if f, e := os.Open(arg[i+1][1:]); m.Assert(e) {
defer f.Close()
if p, e := mp.CreateFormFile(arg[i], path.Base(arg[i+1][1:])); m.Assert(e) {
io.Copy(p, f)
}
}
} else {
mp.WriteField(arg[i], arg[i+1])
}
}
return buf, mp.FormDataContentType()
}
func _spide_head(m *ice.Message, req *http.Request, head map[string]string, value map[string]interface{}) {
m.Info("%s %s", req.Method, req.URL)
kit.Fetch(value[SPIDE_HEADER], func(key string, value string) {
req.Header.Set(key, value)
})
kit.Fetch(value[SPIDE_COOKIE], func(key string, value string) {
req.AddCookie(&http.Cookie{Name: key, Value: value})
m.Info("%s: %s", key, value)
})
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.Info("%s: %s", list[i], list[i+1])
}
for k, v := range head {
req.Header.Set(k, v)
}
if req.Method == SPIDE_POST {
m.Info("%s: %s", req.Header.Get(ContentLength), req.Header.Get(ContentType))
}
}
func _spide_send(m *ice.Message, req *http.Request, timeout string) (*http.Response, error) {
web := m.Target().Server().(*Frame)
if web.Client == nil {
web.Client = &http.Client{Timeout: kit.Duration(timeout)}
}
return web.Client.Do(req)
}
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) {
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])
}
}
m.Resultv(data[ice.MSG_RESULT])
case SPIDE_SAVE:
if f, p, e := kit.Create(save); m.Assert(e) {
defer f.Close()
if n, e := io.Copy(f, res.Body); m.Assert(e) {
m.Log_EXPORT(kit.MDB_SIZE, n, kit.MDB_FILE, p)
m.Echo(p)
}
}
case SPIDE_CACHE:
m.Optionv(RESPONSE, res)
m.Cmdy(CACHE, DOWNLOAD, res.Header.Get(ContentType), uri)
m.Echo(m.Append(DATA))
default:
b, _ := ioutil.ReadAll(res.Body)
var data interface{}
if e := json.Unmarshal(b, &data); e != nil {
m.Echo(string(b))
break
}
m.Optionv(SPIDE_RES, data)
data = kit.KeyValue(map[string]interface{}{}, "", data)
m.Push("", data)
}
}
const ( const (
SPIDE_SHY = "shy" SPIDE_SHY = "shy"
@ -48,8 +273,6 @@ const (
SPIDE_MSG = "msg" SPIDE_MSG = "msg"
SPIDE_SAVE = "save" SPIDE_SAVE = "save"
SPIDE_CACHE = "cache" SPIDE_CACHE = "cache"
SPIDE_PROXY = "proxy"
SPIDE_CB = "spide.cb"
SPIDE_GET = "GET" SPIDE_GET = "GET"
SPIDE_PUT = "PUT" SPIDE_PUT = "PUT"
@ -58,11 +281,13 @@ const (
SPIDE_FORM = "form" SPIDE_FORM = "form"
SPIDE_PART = "part" SPIDE_PART = "part"
SPIDE_JSON = "json"
SPIDE_DATA = "data" SPIDE_DATA = "data"
SPIDE_FILE = "file" SPIDE_FILE = "file"
SPIDE_JSON = "json"
SPIDE_BODY = "body" SPIDE_BODY = "body"
SPIDE_RES = "content_data"
SPIDE_CLIENT = "client" SPIDE_CLIENT = "client"
SPIDE_METHOD = "method" SPIDE_METHOD = "method"
SPIDE_HEADER = "header" SPIDE_HEADER = "header"
@ -81,271 +306,56 @@ const (
REQUEST = "request" REQUEST = "request"
RESPONSE = "response" RESPONSE = "response"
PROTOCOL = "protocol" PROTOCOL = "protocol"
CLIENT_NAME = "client.name"
LOGHEADERS = "logheaders"
) )
const SPIDE = "spide" const SPIDE = "spide"
func init() { func init() {
Index.Merge(&ice.Context{ Index.Merge(&ice.Context{
Configs: map[string]*ice.Config{ Configs: map[string]*ice.Config{
SPIDE: {Name: SPIDE, Help: "蜘蛛侠", Value: kit.Data(kit.MDB_SHORT, "client.name")}, SPIDE: {Name: SPIDE, Help: "蜘蛛侠", Value: kit.Data(kit.MDB_SHORT, CLIENT_NAME)},
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
SPIDE: {Name: "spide client.name action=raw,msg,save,cache method=GET,PUT,POST,DELETE url format=form,part,data,file,json arg 执行:button create", Help: "蜘蛛侠", Action: map[string]*ice.Action{
mdb.CREATE: {Name: "create name address", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
if arg[0] != kit.MDB_NAME {
m.Option(kit.MDB_NAME, arg[0])
m.Option(ADDRESS, arg[1])
}
_spide_create(m, m.Option(kit.MDB_NAME), m.Option(ADDRESS))
}},
mdb.MODIFY: {Name: "modify", Help: "编辑", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(mdb.MODIFY, SPIDE, "", mdb.HASH, CLIENT_NAME, m.Option(CLIENT_NAME), arg)
}},
mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(mdb.DELETE, SPIDE, "", mdb.HASH, CLIENT_NAME, m.Option(CLIENT_NAME))
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) < 2 || arg[0] == "" || (len(arg) > 3 && arg[3] == "") {
m.Fields(len(arg) == 0 || arg[0] == "", "time,client.name,client.url")
m.Cmdy(mdb.SELECT, SPIDE, "", mdb.HASH, CLIENT_NAME, arg)
m.PushAction(mdb.REMOVE)
return
}
_spide_show(m, arg...)
}},
SPIDE_GET: {Name: "GET url key value 执行:button", Help: "蜘蛛侠", Action: map[string]*ice.Action{ SPIDE_GET: {Name: "GET url key value 执行:button", Help: "蜘蛛侠", Action: map[string]*ice.Action{
mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) { mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(mdb.DELETE, SPIDE, "", mdb.HASH, "client.name", m.Option("client.name")) m.Cmdy(mdb.DELETE, SPIDE, "", mdb.HASH, CLIENT_NAME, m.Option(CLIENT_NAME))
}}, }},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Echo(kit.Formats(kit.UnMarshal(m.Cmdx(SPIDE, SPIDE_DEV, SPIDE_RAW, SPIDE_GET, arg[0], arg[1:])))) m.Echo(kit.Formats(kit.UnMarshal(m.Cmdx(SPIDE, SPIDE_DEV, SPIDE_RAW, SPIDE_GET, arg[0], arg[1:]))))
}}, }},
SPIDE_POST: {Name: "POST url key value 执行:button", Help: "蜘蛛侠", Action: map[string]*ice.Action{ SPIDE_POST: {Name: "POST url key value 执行:button", Help: "蜘蛛侠", Action: map[string]*ice.Action{
mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) { mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(mdb.DELETE, SPIDE, "", mdb.HASH, "client.name", m.Option("client.name")) m.Cmdy(mdb.DELETE, SPIDE, "", mdb.HASH, CLIENT_NAME, m.Option(CLIENT_NAME))
}}, }},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Echo(kit.Formats(kit.UnMarshal(m.Cmdx(SPIDE, SPIDE_DEV, SPIDE_RAW, SPIDE_POST, arg[0], SPIDE_JSON, arg[1:])))) m.Echo(kit.Formats(kit.UnMarshal(m.Cmdx(SPIDE, SPIDE_DEV, SPIDE_RAW, SPIDE_POST, arg[0], SPIDE_JSON, arg[1:]))))
}}, }},
SPIDE: {Name: "spide client.name action=raw,msg,save,cache method=GET,PUT,POST,DELETE url format=form,part,json,data,file arg 执行:button create", Help: "蜘蛛侠", Action: map[string]*ice.Action{
mdb.CREATE: {Name: "create name address", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
if arg[0] != "name" {
m.Option("name", arg[0])
m.Option(ADDRESS, arg[1])
}
_spide_create(m, m.Option(kit.MDB_NAME), m.Option(ADDRESS))
}},
mdb.MODIFY: {Name: "modify", Help: "编辑", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(mdb.MODIFY, SPIDE, "", mdb.HASH, "client.name", m.Option("client.name"), arg)
}},
mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(mdb.DELETE, SPIDE, "", mdb.HASH, "client.name", m.Option("client.name"))
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) < 2 || arg[0] == "" || (len(arg) > 3 && arg[3] == "") {
m.Fields(len(arg) == 0 || arg[0] == "", "time,client.name,client.url")
m.Cmdy(mdb.SELECT, SPIDE, "", mdb.HASH, "client.name", arg)
m.PushAction(mdb.REMOVE)
return
}
m.Richs(SPIDE, nil, arg[0], func(key string, value map[string]interface{}) {
client := value[SPIDE_CLIENT].(map[string]interface{})
// 缓存数据
cache, save := "", ""
switch arg[1] {
case SPIDE_RAW, SPIDE_PROXY:
cache, arg = arg[1], arg[1:]
case SPIDE_MSG:
cache, arg = arg[1], arg[1:]
case SPIDE_SAVE:
cache, save, arg = arg[1], arg[2], arg[2:]
case SPIDE_CACHE:
cache, arg = arg[1], arg[1:]
}
// 请求方法
method := kit.Select(SPIDE_POST, client[SPIDE_METHOD])
switch arg = arg[1:]; arg[0] {
case SPIDE_GET:
method, arg = SPIDE_GET, arg[1:]
case SPIDE_PUT:
method, arg = SPIDE_PUT, arg[1:]
case SPIDE_POST:
method, arg = SPIDE_POST, arg[1:]
case SPIDE_DELETE:
method, arg = SPIDE_DELETE, arg[1:]
}
// 请求地址
uri, arg := arg[0], arg[1:]
if strings.HasPrefix(uri, "ftp") {
m.Cmdy(cli.SYSTEM, "wget", uri, arg)
return
}
// 渲染引擎
head := map[string]string{}
body, ok := m.Optionv(SPIDE_BODY).(io.Reader)
if !ok && len(arg) > 0 && method != SPIDE_GET {
switch arg[0] {
case SPIDE_FILE:
if f, e := os.Open(arg[1]); m.Assert(e) {
defer f.Close()
body, arg = f, arg[2:]
}
case SPIDE_DATA:
body, arg = bytes.NewBufferString(arg[1]), arg[2:]
case SPIDE_PART:
buf := &bytes.Buffer{}
mp := multipart.NewWriter(buf)
cache := time.Now().Add(-time.Hour * 240000)
for i := 1; i < len(arg)-1; i += 2 {
if arg[i] == "cache" {
if t, e := time.ParseInLocation(ice.MOD_TIME, arg[i+1], time.Local); e == nil {
cache = t
}
}
if strings.HasPrefix(arg[i+1], "@") {
if s, e := os.Stat(arg[i+1][1:]); e == nil {
if s.ModTime().Before(cache) {
return
}
}
if f, e := os.Open(arg[i+1][1:]); m.Assert(e) {
defer f.Close()
if p, e := mp.CreateFormFile(arg[i], path.Base(arg[i+1][1:])); m.Assert(e) {
io.Copy(p, f)
}
}
} else {
mp.WriteField(arg[i], arg[i+1])
}
}
mp.Close()
head[ContentType] = mp.FormDataContentType()
body = buf
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
case SPIDE_JSON:
arg = arg[1:]
fallthrough
default:
data := map[string]interface{}{}
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.Log_EXPORT(SPIDE_JSON, kit.Format(data))
}
arg = arg[:0]
} else {
body = bytes.NewBuffer([]byte{})
}
// 请求地址
uri = kit.MergeURL2(kit.Format(client["url"]), uri, arg)
req, e := http.NewRequest(method, uri, body)
m.Info("%s %s", req.Method, req.URL)
m.Assert(e)
// 请求变量
kit.Fetch(value[SPIDE_HEADER], func(key string, value string) {
req.Header.Set(key, value)
})
kit.Fetch(value[SPIDE_COOKIE], func(key string, value string) {
req.AddCookie(&http.Cookie{Name: key, Value: value})
m.Info("%s: %s", key, value)
})
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.Info("%s: %s", list[i], list[i+1])
}
for k, v := range head {
req.Header.Set(k, v)
}
// 请求代理
web := m.Target().Server().(*Frame)
if web.Client == nil {
web.Client = &http.Client{Timeout: kit.Duration(kit.Format(client["timeout"]))}
}
if req.Method == SPIDE_POST {
m.Info("%s: %s", req.Header.Get(ContentLength), req.Header.Get(ContentType))
}
// 发送请求
res, e := web.Client.Do(req)
if m.Warn(e != nil, ice.ErrNotFound, e) {
return
}
// 检查结果
defer res.Body.Close()
m.Cost("status", res.Status, "length", res.Header.Get(ContentLength), "type", res.Header.Get(ContentType))
switch cb := m.Optionv(SPIDE_CB).(type) {
case func(*ice.Message, *http.Request, *http.Response):
cb(m, req, res)
return
}
if m.Warn(res.StatusCode != http.StatusOK, res.Status) {
m.Set(ice.MSG_RESULT)
// return
switch res.StatusCode {
case http.StatusNotFound:
return
default:
}
}
// 缓存变量
for _, v := range res.Cookies() {
kit.Value(value, "cookie."+v.Name, v.Value)
m.Log(ice.LOG_IMPORT, "%s: %s", v.Name, v.Value)
}
// 解析引擎
switch cache {
case SPIDE_PROXY:
m.Optionv(RESPONSE, res)
m.Cmdy(CACHE, DOWNLOAD, res.Header.Get(ContentType), uri)
m.Echo(m.Append(DATA))
case SPIDE_CACHE:
m.Optionv(RESPONSE, res)
m.Cmdy(CACHE, DOWNLOAD, res.Header.Get(ContentType), uri)
m.Echo(m.Append(DATA))
case SPIDE_SAVE:
if f, p, e := kit.Create(save); m.Assert(e) {
if n, e := io.Copy(f, res.Body); m.Assert(e) {
m.Log_EXPORT(kit.MDB_SIZE, n, kit.MDB_FILE, p)
m.Echo(p)
}
}
case SPIDE_RAW:
b, _ := ioutil.ReadAll(res.Body)
if 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])
}
}
m.Resultv(data[ice.MSG_RESULT])
default:
b, _ := ioutil.ReadAll(res.Body)
var data interface{}
if e := json.Unmarshal(b, &data); e != nil {
m.Echo(string(b))
break
}
m.Optionv("content_data", data)
data = kit.KeyValue(map[string]interface{}{}, "", data)
m.Push("", data)
}
})
}},
}}) }})
} }

View File

@ -1,12 +1,13 @@
package web package web
import ( import (
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/nfs"
kit "github.com/shylinux/toolkits"
"os" "os"
"time" "time"
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/mdb"
"github.com/shylinux/icebergs/base/nfs"
kit "github.com/shylinux/toolkits"
) )
func _story_list(m *ice.Message, name string, key string) { func _story_list(m *ice.Message, name string, key string) {
@ -14,7 +15,7 @@ func _story_list(m *ice.Message, name string, key string) {
m.Richs(STORY, HEAD, kit.MDB_FOREACH, func(key string, value map[string]interface{}) { m.Richs(STORY, HEAD, kit.MDB_FOREACH, func(key string, value map[string]interface{}) {
m.Push(key, value, []string{kit.MDB_TIME, kit.MDB_COUNT, STORY}) m.Push(key, value, []string{kit.MDB_TIME, kit.MDB_COUNT, STORY})
}) })
m.Sort(kit.MDB_TIME, "time_r") m.SortTimeR(kit.MDB_TIME)
return return
} }
if key == "" { if key == "" {
@ -23,7 +24,7 @@ func _story_list(m *ice.Message, name string, key string) {
} }
m.Richs(STORY, nil, key, func(key string, value map[string]interface{}) { m.Richs(STORY, nil, key, func(key string, value map[string]interface{}) {
m.Push("detail", value) m.Push(mdb.DETAIL, value)
}) })
} }
@ -57,7 +58,7 @@ func _story_index(m *ice.Message, name string, withdata bool) {
func _story_history(m *ice.Message, name string) { func _story_history(m *ice.Message, name string) {
// 历史记录 // 历史记录
list := m.Cmd(STORY, INDEX, name).Append(LIST) list := m.Cmd(STORY, INDEX, name).Append(LIST)
for i := 0; i < kit.Int(kit.Select("30", m.Option("cache.limit"))) && list != ""; i++ { for i := 0; i < kit.Int(kit.Select("30", m.Option(mdb.CACHE_LIMIT))) && list != ""; i++ {
m.Richs(STORY, nil, list, func(key string, value map[string]interface{}) { m.Richs(STORY, nil, list, func(key string, value map[string]interface{}) {
// 直连节点 // 直连节点
m.Push(key, value, []string{kit.MDB_TIME, kit.MDB_KEY, kit.MDB_COUNT, SCENE, STORY}) m.Push(key, value, []string{kit.MDB_TIME, kit.MDB_KEY, kit.MDB_COUNT, SCENE, STORY})
@ -155,9 +156,11 @@ const (
PUSH = "push" PUSH = "push"
COMMIT = "commit" COMMIT = "commit"
) )
const SCENE = "scene" const (
SCENE = "scene"
DRAMA = "drama"
)
const STORY = "story" const STORY = "story"
const DRAMA = "drama"
func init() { func init() {
Index.Merge(&ice.Context{ Index.Merge(&ice.Context{
@ -184,9 +187,6 @@ func init() {
HISTORY: {Name: "history name", Help: "历史", Hand: func(m *ice.Message, arg ...string) { HISTORY: {Name: "history name", Help: "历史", Hand: func(m *ice.Message, arg ...string) {
_story_history(m, arg[0]) _story_history(m, arg[0])
}}, }},
"add": {Name: "add type name text arg...", Help: "淘汰", Hand: func(m *ice.Message, arg ...string) {
panic(m)
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
_story_list(m, kit.Select("", arg, 0), kit.Select("", arg, 1)) _story_list(m, kit.Select("", arg, 0), kit.Select("", arg, 1))
}}, }},

View File

@ -1,15 +1,15 @@
package web package web
import ( import (
"net"
"net/http"
"path"
ice "github.com/shylinux/icebergs" ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/cli" "github.com/shylinux/icebergs/base/cli"
"github.com/shylinux/icebergs/base/mdb" "github.com/shylinux/icebergs/base/mdb"
"github.com/shylinux/icebergs/base/tcp" "github.com/shylinux/icebergs/base/tcp"
kit "github.com/shylinux/toolkits" kit "github.com/shylinux/toolkits"
"net"
"net/http"
"path"
) )
type Frame struct { type Frame struct {
@ -43,16 +43,16 @@ func (web *Frame) Start(m *ice.Message, arg ...string) bool {
// 静态路由 // 静态路由
msg := m.Spawn(s) msg := m.Spawn(s)
m.Confm(SERVE, "meta.static", func(key string, value string) { m.Confm(SERVE, kit.Keym("static"), func(key string, value string) {
m.Log("route", "%s <- %s <- %s", s.Name, key, value) m.Log("route", "%s <- %s <- %s", s.Name, key, value)
w.Handle(key, http.StripPrefix(key, http.FileServer(http.Dir(value)))) w.Handle(key, http.StripPrefix(key, http.FileServer(http.Dir(value))))
}) })
// 级联路由 // 级联路由
route := "/" + s.Name + "/" route := "/" + s.Name + "/"
if n, ok := p.Server().(*Frame); ok && n.ServeMux != nil { if f, ok := p.Server().(*Frame); ok && f.ServeMux != nil {
msg.Log("route", "%s <= %s", p.Name, route) msg.Log("route", "%s <= %s", p.Name, route)
n.Handle(route, http.StripPrefix(path.Dir(route), w)) f.Handle(route, http.StripPrefix(path.Dir(route), w))
} }
// 命令路由 // 命令路由
@ -70,7 +70,7 @@ func (web *Frame) Start(m *ice.Message, arg ...string) bool {
}) })
web.m, web.Server = m, &http.Server{Handler: web} web.m, web.Server = m, &http.Server{Handler: web}
m.Option(tcp.LISTEN_CB, func(l net.Listener) { m.Option(kit.Keycb(tcp.LISTEN), func(l net.Listener) {
m.Cmdy(mdb.INSERT, SERVE, "", mdb.HASH, arg, kit.MDB_STATUS, tcp.START, kit.MDB_PROTO, m.Option(kit.MDB_PROTO), SPIDE_DEV, m.Option(SPIDE_DEV)) m.Cmdy(mdb.INSERT, SERVE, "", mdb.HASH, arg, kit.MDB_STATUS, tcp.START, kit.MDB_PROTO, m.Option(kit.MDB_PROTO), SPIDE_DEV, m.Option(SPIDE_DEV))
defer m.Cmd(mdb.MODIFY, SERVE, "", mdb.HASH, kit.MDB_NAME, m.Option(kit.MDB_NAME), kit.MDB_STATUS, tcp.STOP) defer m.Cmd(mdb.MODIFY, SERVE, "", mdb.HASH, kit.MDB_NAME, m.Option(kit.MDB_NAME), kit.MDB_STATUS, tcp.STOP)
@ -93,18 +93,18 @@ var Index = &ice.Context{Name: WEB, Help: "网络模块",
ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Load() m.Load()
m.Conf(SPACE, kit.MDB_HASH, "") m.Conf(SPACE, kit.MDB_HASH, "")
m.Cmd(mdb.SEARCH, mdb.CREATE, SPACE, m.Prefix(SPACE))
m.Cmd(SPIDE, mdb.CREATE, SPIDE_DEV, kit.Select("http://:9020", m.Conf(cli.RUNTIME, "conf.ctx_dev"))) m.Cmd(SPIDE, mdb.CREATE, SPIDE_DEV, kit.Select("http://:9020", m.Conf(cli.RUNTIME, "conf.ctx_dev")))
m.Cmd(SPIDE, mdb.CREATE, SPIDE_SELF, kit.Select("http://:9020", m.Conf(cli.RUNTIME, "conf.ctx_self"))) m.Cmd(SPIDE, mdb.CREATE, SPIDE_SELF, kit.Select("http://:9020", m.Conf(cli.RUNTIME, "conf.ctx_self")))
m.Cmd(SPIDE, mdb.CREATE, SPIDE_SHY, kit.Select("https://shylinux.com:443", m.Conf(cli.RUNTIME, "conf.ctx_shy"))) m.Cmd(SPIDE, mdb.CREATE, SPIDE_SHY, kit.Select("https://shylinux.com:443", m.Conf(cli.RUNTIME, "conf.ctx_shy")))
m.Cmd(mdb.SEARCH, mdb.CREATE, SPACE, m.Prefix(SPACE))
}}, }},
ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Save() m.Save()
m.Done(true) m.Done(true)
m.Cmd(SERVE).Table(func(index int, value map[string]string, head []string) { m.Cmd(SERVE).Table(func(index int, value map[string]string, head []string) {
m.Done(value[kit.MDB_STATUS] == "start") m.Done(value[kit.MDB_STATUS] == tcp.START)
}) })
}}, }},
}, },
@ -112,7 +112,7 @@ var Index = &ice.Context{Name: WEB, Help: "网络模块",
func init() { func init() {
ice.Index.Register(Index, &Frame{}, ice.Index.Register(Index, &Frame{},
ROUTE, SERVE, SPACE, DREAM, SPIDE, CACHE, STORY, ROUTE,
SPIDE, SHARE, CACHE, STORY, SHARE, SERVE, SPACE, DREAM,
) )
} }

View File

@ -1,12 +1,16 @@
chapter "web" chapter "web"
label "web" `
spide cache story route
share serve space dream
`
field "蜘蛛侠" web.spide
field "缓存池" web.cache
field "故事会" web.story
field "路由器" web.route field "路由器" web.route
field "共享链" web.share
field "服务器" web.serve field "服务器" web.serve
field "空间站" web.space field "空间站" web.space
field "梦想家" web.dream field "梦想家" web.dream
field "蜘蛛侠" web.spide
field "共享链" web.share
field "缓存池" web.cache
field "故事会" web.story

36
conf.go
View File

@ -14,11 +14,11 @@ const ( // MOD
const ( // REPOS const ( // REPOS
VOLCANOS = "volcanos" VOLCANOS = "volcanos"
ICEBERGS = "icebergs" ICEBERGS = "icebergs"
CONTEXTS = "contexts"
INTSHELL = "intshell" INTSHELL = "intshell"
CONTEXTS = "contexts"
REQUIRE = "require"
PUBLISH = "publish" PUBLISH = "publish"
REQUIRE = "require"
SUCCESS = "success" SUCCESS = "success"
FAILURE = "failure" FAILURE = "failure"
@ -26,6 +26,7 @@ const ( // REPOS
) )
const ( // DIR const ( // DIR
USR_VOLCANOS = "usr/volcanos" USR_VOLCANOS = "usr/volcanos"
USR_ICEBERGS = "usr/icebergs"
USR_INTSHELL = "usr/intshell" USR_INTSHELL = "usr/intshell"
USR_PUBLISH = "usr/publish" USR_PUBLISH = "usr/publish"
USR_INSTALL = "usr/install" USR_INSTALL = "usr/install"
@ -33,23 +34,30 @@ const ( // DIR
PROTO_JS = "proto.js" PROTO_JS = "proto.js"
FRAME_JS = "frame.js" FRAME_JS = "frame.js"
INDEX_JS = "index.js"
ORDER_JS = "order.js"
ORDER_SH = "order.sh"
INDEX_SH = "index.sh"
VAR_TMP = "var/tmp"
VAR_LOG = "var/log" VAR_LOG = "var/log"
VAR_CONF = "var/conf" VAR_CONF = "var/conf"
VAR_DATA = "var/data"
VAR_FILE = "var/file"
VAR_PROXY = "var/proxy"
VAR_TRASH = "var/trash" VAR_TRASH = "var/trash"
ETC_MISS = "etc/miss.sh" BIN_ICE = "bin/ice.sh"
BIN_ICE_BIN = "bin/ice.bin"
BIN_BOOTLOG = "bin/boot.log"
ETC_INIT = "etc/init.shy" ETC_INIT = "etc/init.shy"
ETC_EXIT = "etc/exit.shy" ETC_EXIT = "etc/exit.shy"
ETC_MISS = "etc/miss.sh"
SRC_MAIN = "src/main.shy" SRC_MAIN = "src/main.shy"
SRC_MAIN_GO = "src/main.go" SRC_MAIN_GO = "src/main.go"
SRC_VERSION = "src/version.go" SRC_VERSION = "src/version.go"
SRC_BINPACK = "src/binpack.go" SRC_BINPACK = "src/binpack.go"
BIN_BOOTLOG = "bin/boot.log"
BIN_ICE_BIN = "bin/ice.bin"
BIN_ICE = "bin/ice.sh"
MAKEFILE = "makefile" MAKEFILE = "makefile"
ORDER_SH = "order.sh"
ORDER_JS = "order.js"
GO_MOD = "go.mod" GO_MOD = "go.mod"
GO_SUM = "go.sum" GO_SUM = "go.sum"
@ -75,9 +83,8 @@ const ( // MSG
MSG_ACTION = "_action" MSG_ACTION = "_action"
MSG_STATUS = "_status" MSG_STATUS = "_status"
MSG_CONTROL = "_control"
MSG_PROCESS = "_process"
MSG_DISPLAY = "_display" MSG_DISPLAY = "_display"
MSG_PROCESS = "_process"
MSG_CMDS = "cmds" MSG_CMDS = "cmds"
MSG_SESSID = "sessid" MSG_SESSID = "sessid"
@ -113,10 +120,10 @@ const ( // RENDER
RENDER_TEMPLATE = "_template" RENDER_TEMPLATE = "_template"
) )
const ( // PROCESS const ( // PROCESS
PROCESS_PROGRESS = "_progress" PROCESS_REFRESH = "_refresh"
PROCESS_REFRESH = "_refresh" PROCESS_REWRITE = "_rewrite"
PROCESS_FIELD = "_field" PROCESS_FIELD = "_field"
PROCESS_INNER = "_inner" PROCESS_INNER = "_inner"
PROCESS_HOLD = "_hold" PROCESS_HOLD = "_hold"
PROCESS_BACK = "_back" PROCESS_BACK = "_back"
@ -124,7 +131,6 @@ const ( // PROCESS
PROCESS_OPEN = "_open" PROCESS_OPEN = "_open"
FIELD_PREFIX = "_prefix" FIELD_PREFIX = "_prefix"
CONTROL_PAGE = "_page"
) )
const ( // LOG const ( // LOG
// 数据 // 数据

View File

@ -241,8 +241,7 @@ func init() {
} }
// 命令插件 // 命令插件
m.Option(ice.MSG_PROCESS, "_field") m.ProcessField(arg[0], arg[1], "run")
m.Option("_prefix", arg[0], arg[1], "run")
m.Table(func(index int, value map[string]string, head []string) { m.Table(func(index int, value map[string]string, head []string) {
m.Cmdy(web.SPACE, value[POD], ctx.CONTEXT, value[CTX], ctx.COMMAND, value[CMD]) m.Cmdy(web.SPACE, value[POD], ctx.CONTEXT, value[CTX], ctx.COMMAND, value[CMD])
}) })

View File

@ -140,7 +140,7 @@ func init() {
_autogen_version(m) _autogen_version(m)
m.Cmd(BINPACK, mdb.CREATE) m.Cmd(BINPACK, mdb.CREATE)
}}, }},
mdb.SCRIPT: {Name: "script", Help: "脚本", Hand: func(m *ice.Message, arg ...string) { "script": {Name: "script", Help: "脚本", Hand: func(m *ice.Message, arg ...string) {
_autogen_miss(m) _autogen_miss(m)
}}, }},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {

View File

@ -50,7 +50,7 @@ func _bench_http(m *ice.Message, name, target string, arg ...string) {
m.Echo(s.Show()) m.Echo(s.Show())
m.Echo("body: %d\n", body) m.Echo("body: %d\n", body)
m.Option(ice.MSG_PROCESS, ice.PROCESS_INNER) m.ProcessInner()
} }
func _bench_redis(m *ice.Message, name, target string, arg ...string) { func _bench_redis(m *ice.Message, name, target string, arg ...string) {
} }

View File

@ -46,7 +46,7 @@ func init() {
value = kit.GetMeta(value) value = kit.GetMeta(value)
p := 0 p := 0
m.Optionv(web.DOWNLOAD_CB, func(size int, total int) { m.Optionv(kit.Keycb(web.DOWNLOAD), func(size int, total int) {
if n := size * 100 / total; p != n { if n := size * 100 / total; p != n {
value[kit.SSH_STEP], value[kit.MDB_SIZE], value[kit.MDB_TOTAL] = n, size, total value[kit.SSH_STEP], value[kit.MDB_SIZE], value[kit.MDB_TOTAL] = n, size, total
toast(name, size, total) toast(name, size, total)

View File

@ -73,15 +73,15 @@ func init() {
m.Cmd(mdb.INSERT, PPROF, _sub_key(m, m.Option(kit.MDB_ZONE)), mdb.LIST, kit.MDB_TEXT, strings.Join(res, "\n"), kit.MDB_FILE, msg.Append(kit.MDB_FILE)) m.Cmd(mdb.INSERT, PPROF, _sub_key(m, m.Option(kit.MDB_ZONE)), mdb.LIST, kit.MDB_TEXT, strings.Join(res, "\n"), kit.MDB_FILE, msg.Append(kit.MDB_FILE))
m.Echo(strings.Join(res, "\n")) m.Echo(strings.Join(res, "\n"))
m.Option(ice.MSG_PROCESS, ice.PROCESS_INNER) m.ProcessInner()
}}, }},
web.SERVE: {Name: "serve", Help: "展示", Hand: func(m *ice.Message, arg ...string) { web.SERVE: {Name: "serve", Help: "展示", Hand: func(m *ice.Message, arg ...string) {
m.Option(ice.MSG_PROCESS, ice.PROCESS_INNER)
u := kit.ParseURL(m.Option(ice.MSG_USERWEB)) u := kit.ParseURL(m.Option(ice.MSG_USERWEB))
p := u.Hostname() + ":" + m.Cmdx(tcp.PORT, aaa.RIGHT) p := u.Hostname() + ":" + m.Cmdx(tcp.PORT, aaa.RIGHT)
m.Cmd(cli.DAEMON, m.Confv(PPROF, "meta.pprof"), "-http="+p, m.Option(BINNARY), m.Option(kit.MDB_FILE)) m.Cmd(cli.DAEMON, m.Confv(PPROF, "meta.pprof"), "-http="+p, m.Option(BINNARY), m.Option(kit.MDB_FILE))
m.Echo("http://%s/ui/top", p) m.Echo("http://%s/ui/top", p)
m.ProcessInner()
}}, }},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Option(mdb.FIELDS, kit.Select("time,count,zone,binnary,service,seconds", kit.Select("time,id,text,binnary,file", mdb.DETAIL, len(arg) > 1), len(arg) > 0)) m.Option(mdb.FIELDS, kit.Select("time,count,zone,binnary,service,seconds", kit.Select("time,id,text,binnary,file", mdb.DETAIL, len(arg) > 1), len(arg) > 0))

View File

@ -47,7 +47,7 @@ func _asset_list(m *ice.Message, account string, id string) {
func _asset_check(m *ice.Message, account string) { func _asset_check(m *ice.Message, account string) {
amount := 0 amount := 0
m.Option(mdb.FIELDS, "time,id,type,amount,name,text") m.Option(mdb.FIELDS, "time,id,type,amount,name,text")
m.Option(mdb.SELECT_CB, func(fields []string, value map[string]interface{}) { m.Option(kit.Keycb(mdb.SELECT), func(fields []string, value map[string]interface{}) {
amount += kit.Int(kit.Value(value, AMOUNT)) amount += kit.Int(kit.Value(value, AMOUNT))
}) })
m.Cmd(mdb.SELECT, ASSET, _sub_key(m, account), mdb.LIST) m.Cmd(mdb.SELECT, ASSET, _sub_key(m, account), mdb.LIST)

View File

@ -21,7 +21,7 @@ func init() {
mdb.INSERT: {Name: "insert zone type=once,step,week name text begin_time@date close_time@date", Help: "添加", Hand: func(m *ice.Message, arg ...string) { mdb.INSERT: {Name: "insert zone type=once,step,week name text begin_time@date close_time@date", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
_task_create(m, arg[1]) _task_create(m, arg[1])
_task_insert(m, arg[1], arg[2:]...) _task_insert(m, arg[1], arg[2:]...)
m.Option(ice.MSG_PROCESS, ice.PROCESS_REFRESH) m.ProcessRefresh("1ms")
}}, }},
mdb.MODIFY: {Name: "modify", Help: "编辑", Hand: func(m *ice.Message, arg ...string) { mdb.MODIFY: {Name: "modify", Help: "编辑", Hand: func(m *ice.Message, arg ...string) {
_task_modify(m, m.Option(kit.MDB_ZONE), m.Option(kit.MDB_ID), arg[0], arg[1]) _task_modify(m, m.Option(kit.MDB_ZONE), m.Option(kit.MDB_ID), arg[0], arg[1])
@ -31,7 +31,7 @@ func init() {
}}, }},
mdb.IMPORT: {Name: "import", Help: "导入", Hand: func(m *ice.Message, arg ...string) { mdb.IMPORT: {Name: "import", Help: "导入", Hand: func(m *ice.Message, arg ...string) {
_task_import(m, "") _task_import(m, "")
m.Option(ice.MSG_PROCESS, ice.PROCESS_REFRESH) m.ProcessRefresh("1ms")
}}, }},
mdb.INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) { mdb.INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) {
_task_inputs(m, kit.Select("", arg, 0), kit.Select("", arg, 1)) _task_inputs(m, kit.Select("", arg, 0), kit.Select("", arg, 1))
@ -61,7 +61,7 @@ func init() {
begin_time, end_time := _task_scope(m, 8, arg...) begin_time, end_time := _task_scope(m, 8, arg...)
m.Option(mdb.CACHE_LIMIT, "100") m.Option(mdb.CACHE_LIMIT, "100")
m.Option(mdb.FIELDS, "begin_time,close_time,zone,id,level,status,score,type,name,text,extra") m.Option(mdb.FIELDS, "begin_time,close_time,zone,id,level,status,score,type,name,text,extra")
m.Option(mdb.SELECT_CB, func(key string, fields []string, value, val map[string]interface{}) { m.Option(kit.Keycb(mdb.SELECT), func(key string, fields []string, value, val map[string]interface{}) {
begin, _ := time.ParseInLocation(ice.MOD_TIME, kit.Format(value[TaskField.BEGIN_TIME]), time.Local) begin, _ := time.ParseInLocation(ice.MOD_TIME, kit.Format(value[TaskField.BEGIN_TIME]), time.Local)
if begin_time.After(begin) || begin.After(end_time) { if begin_time.After(begin) || begin.After(end_time) {
return return

13
misc.go
View File

@ -314,14 +314,23 @@ func (m *Message) Process(action string, arg ...interface{}) {
m.Option(MSG_PROCESS, action) m.Option(MSG_PROCESS, action)
m.Option("_arg", arg...) m.Option("_arg", arg...)
} }
func (m *Message) ProcessRewrite(arg ...interface{}) {
m.Process(PROCESS_REWRITE)
m.Option("_arg", arg...)
}
func (m *Message) ProcessRefresh(delay string) { func (m *Message) ProcessRefresh(delay string) {
if d, e := time.ParseDuration(delay); e == nil { if d, e := time.ParseDuration(delay); e == nil {
m.Option("_delay", int(d/time.Millisecond)) m.Option("_delay", int(d/time.Millisecond))
} }
m.Process(PROCESS_REFRESH) m.Process(PROCESS_REFRESH)
} }
func (m *Message) ProcessHold() { m.Process(PROCESS_HOLD) } func (m *Message) ProcessField(arg ...interface{}) {
func (m *Message) ProcessBack() { m.Process(PROCESS_BACK) } m.Process(PROCESS_FIELD)
m.Option("_prefix", arg...)
}
func (m *Message) ProcessInner() { m.Process(PROCESS_INNER) }
func (m *Message) ProcessHold() { m.Process(PROCESS_HOLD) }
func (m *Message) ProcessBack() { m.Process(PROCESS_BACK) }
func (m *Message) Upload(dir string) { func (m *Message) Upload(dir string) {
up := kit.Simple(m.Optionv(MSG_UPLOAD)) up := kit.Simple(m.Optionv(MSG_UPLOAD))

View File

@ -56,7 +56,6 @@ func init() {
m.Option(mdb.FIELDS, mdb.DETAIL) m.Option(mdb.FIELDS, mdb.DETAIL)
} else { } else {
m.Option(mdb.FIELDS, m.Conf(SYNC, kit.META_FIELD)) m.Option(mdb.FIELDS, m.Conf(SYNC, kit.META_FIELD))
m.Option(ice.MSG_CONTROL, ice.CONTROL_PAGE)
defer m.PushAction(cli.SYSTEM, FAVOR) defer m.PushAction(cli.SYSTEM, FAVOR)
} }

View File

@ -35,7 +35,7 @@ func init() {
) )
m.Option("progress", m.Prefix(CACHE), "", m.Option(kit.MDB_LINK)) m.Option("progress", m.Prefix(CACHE), "", m.Option(kit.MDB_LINK))
m.Option(web.DOWNLOAD_CB, m.Prefix(CACHE), "", kit.Keys(kit.MDB_HASH, h)) m.Option(kit.Keycb(web.DOWNLOAD), m.Prefix(CACHE), "", kit.Keys(kit.MDB_HASH, h))
msg := m.Cmd("web.spide", web.SPIDE_DEV, web.SPIDE_CACHE, web.SPIDE_GET, m.Option(kit.MDB_LINK)) msg := m.Cmd("web.spide", web.SPIDE_DEV, web.SPIDE_CACHE, web.SPIDE_GET, m.Option(kit.MDB_LINK))
p := path.Join(m.Conf(m.Prefix(CACHE), kit.META_PATH), m.Option(kit.MDB_NAME)) p := path.Join(m.Conf(m.Prefix(CACHE), kit.META_PATH), m.Option(kit.MDB_NAME))

View File

@ -109,8 +109,8 @@ func init() {
m.ProcessHold() m.ProcessHold()
}}, }},
MAKE: {Name: "make", Help: "编译", Hand: func(m *ice.Message, arg ...string) { MAKE: {Name: "make", Help: "编译", Hand: func(m *ice.Message, arg ...string) {
m.Toast("doing", "make", 100000) m.Toast("building", MAKE, 100000)
defer m.Toast("success", "make", 1000) defer m.Toast("success", MAKE, 1000)
m.Cmdy(cli.SYSTEM, MAKE) m.Cmdy(cli.SYSTEM, MAKE)
}}, }},
@ -143,7 +143,7 @@ func init() {
}}, }},
mdb.INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) { mdb.INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) {
switch arg[0] { switch arg[0] {
case "name": case kit.MDB_NAME:
m.OptionFields("name,time") m.OptionFields("name,time")
m.Cmdy(REPOS) m.Cmdy(REPOS)

View File

@ -17,9 +17,10 @@ import (
"time" "time"
) )
func _lark_get(m *ice.Message, bot string, arg ...interface{}) *ice.Message { func _lark_get(m *ice.Message, bot string, arg ...interface{}) (*ice.Message, interface{}) {
m.Option(web.SPIDE_HEADER, "Authorization", "Bearer "+m.Cmdx(APP, TOKEN, bot), web.ContentType, web.ContentJSON) m.Option(web.SPIDE_HEADER, "Authorization", "Bearer "+m.Cmdx(APP, TOKEN, bot), web.ContentType, web.ContentJSON)
return m.Cmd(web.SPIDE, LARK, http.MethodGet, arg) msg := m.Cmd(web.SPIDE, LARK, http.MethodGet, arg)
return msg, msg.Optionv(web.SPIDE_RES)
} }
func _lark_post(m *ice.Message, bot string, arg ...interface{}) *ice.Message { func _lark_post(m *ice.Message, bot string, arg ...interface{}) *ice.Message {
m.Option(web.SPIDE_HEADER, "Authorization", "Bearer "+m.Cmdx(APP, TOKEN, bot), web.ContentType, web.ContentJSON) m.Option(web.SPIDE_HEADER, "Authorization", "Bearer "+m.Cmdx(APP, TOKEN, bot), web.ContentType, web.ContentJSON)
@ -125,16 +126,16 @@ var Index = &ice.Context{Name: LARK, Help: "机器人",
}}, }},
COMPANY: {Name: "company ship_id open_id text auto", Help: "组织", Action: map[string]*ice.Action{ COMPANY: {Name: "company ship_id open_id text auto", Help: "组织", Action: map[string]*ice.Action{
"info": {Name: "info ship_id", Hand: func(m *ice.Message, arg ...string) { "info": {Name: "info ship_id", Hand: func(m *ice.Message, arg ...string) {
msg := _lark_get(m, "bot", "/open-apis/contact/v1/department/detail/batch_get", "department_ids", m.Option(SHIP_ID)) _, data := _lark_get(m, "bot", "/open-apis/contact/v1/department/detail/batch_get", "department_ids", m.Option(SHIP_ID))
kit.Fetch(kit.Value(msg.Optionv("content_data"), "data.department_infos"), func(index int, value map[string]interface{}) { kit.Fetch(kit.Value(data, "data.department_infos"), func(index int, value map[string]interface{}) {
m.Push("", value) m.Push("", value)
}) })
}}, }},
"list": {Name: "list ship_id", Hand: func(m *ice.Message, arg ...string) { "list": {Name: "list ship_id", Hand: func(m *ice.Message, arg ...string) {
msg := _lark_get(m, "bot", "/open-apis/contact/v1/department/user/list", _, data := _lark_get(m, "bot", "/open-apis/contact/v1/department/user/list",
"department_id", m.Option(SHIP_ID), "page_size", "100", "fetch_child", "true") "department_id", m.Option(SHIP_ID), "page_size", "100", "fetch_child", "true")
kit.Fetch(kit.Value(msg.Optionv("content_data"), "data.user_list"), func(index int, value map[string]interface{}) { kit.Fetch(kit.Value(data, "data.user_list"), func(index int, value map[string]interface{}) {
msg := m.Cmd(EMPLOYEE, value[OPEN_ID]) msg := m.Cmd(EMPLOYEE, value[OPEN_ID])
m.PushImages(aaa.AVATAR, msg.Append("avatar_72")) m.PushImages(aaa.AVATAR, msg.Append("avatar_72"))
m.Push(aaa.GENDER, kit.Select("女", "男", msg.Append(aaa.GENDER) == "1")) m.Push(aaa.GENDER, kit.Select("女", "男", msg.Append(aaa.GENDER) == "1"))
@ -145,8 +146,8 @@ var Index = &ice.Context{Name: LARK, Help: "机器人",
}}, }},
}, Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { }, Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
if len(arg) == 0 { // 组织列表 if len(arg) == 0 { // 组织列表
msg := _lark_get(m, "bot", "/open-apis/contact/v1/scope/get/") _, data := _lark_get(m, "bot", "/open-apis/contact/v1/scope/get/")
kit.Fetch(kit.Value(msg.Optionv("content_data"), "data.authed_departments"), func(index int, value string) { kit.Fetch(kit.Value(data, "data.authed_departments"), func(index int, value string) {
m.Push(SHIP_ID, value) m.Push(SHIP_ID, value)
msg := m.Cmd(COMPANY, "info", value) msg := m.Cmd(COMPANY, "info", value)
m.Push(kit.MDB_NAME, msg.Append(kit.MDB_NAME)) m.Push(kit.MDB_NAME, msg.Append(kit.MDB_NAME))
@ -170,8 +171,8 @@ var Index = &ice.Context{Name: LARK, Help: "机器人",
return return
} }
if strings.HasPrefix(arg[0], "ou_") { if strings.HasPrefix(arg[0], "ou_") {
msg := _lark_get(m, "bot", "/open-apis/contact/v1/user/batch_get", "open_ids", arg[0]) _, data := _lark_get(m, "bot", "/open-apis/contact/v1/user/batch_get", "open_ids", arg[0])
kit.Fetch(kit.Value(msg.Optionv("content_data"), "data.user_infos"), func(index int, value map[string]interface{}) { kit.Fetch(kit.Value(data, "data.user_infos"), func(index int, value map[string]interface{}) {
m.Push(mdb.DETAIL, value) m.Push(mdb.DETAIL, value)
}) })
return return
@ -189,8 +190,8 @@ var Index = &ice.Context{Name: LARK, Help: "机器人",
}}, }},
GROUP: {Name: "group chat_id open_id text auto", Help: "群组", Action: map[string]*ice.Action{ GROUP: {Name: "group chat_id open_id text auto", Help: "群组", Action: map[string]*ice.Action{
"list": {Name: "list chat_id", Hand: func(m *ice.Message, arg ...string) { "list": {Name: "list chat_id", Hand: func(m *ice.Message, arg ...string) {
msg := _lark_get(m, "bot", "/open-apis/chat/v4/info", "chat_id", m.Option(CHAT_ID)) _, data := _lark_get(m, "bot", "/open-apis/chat/v4/info", "chat_id", m.Option(CHAT_ID))
kit.Fetch(kit.Value(msg.Optionv("content_data"), "data.members"), func(index int, value map[string]interface{}) { kit.Fetch(kit.Value(data, "data.members"), func(index int, value map[string]interface{}) {
msg := m.Cmd(EMPLOYEE, value[OPEN_ID]) msg := m.Cmd(EMPLOYEE, value[OPEN_ID])
m.PushImages(aaa.AVATAR, msg.Append("avatar_72")) m.PushImages(aaa.AVATAR, msg.Append("avatar_72"))
m.Push(aaa.GENDER, kit.Select("女", "男", msg.Append(aaa.GENDER) == "1")) m.Push(aaa.GENDER, kit.Select("女", "男", msg.Append(aaa.GENDER) == "1"))
@ -201,8 +202,8 @@ var Index = &ice.Context{Name: LARK, Help: "机器人",
}}, }},
}, Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { }, Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
if len(arg) == 0 { // 群组列表 if len(arg) == 0 { // 群组列表
msg := _lark_get(m, "bot", "/open-apis/chat/v4/list") _, data := _lark_get(m, "bot", "/open-apis/chat/v4/list")
kit.Fetch(kit.Value(msg.Optionv("content_data"), "data.groups"), func(index int, value map[string]interface{}) { kit.Fetch(kit.Value(data, "data.groups"), func(index int, value map[string]interface{}) {
m.Push(CHAT_ID, value[CHAT_ID]) m.Push(CHAT_ID, value[CHAT_ID])
m.PushImages(aaa.AVATAR, kit.Format(value[aaa.AVATAR]), "72") m.PushImages(aaa.AVATAR, kit.Format(value[aaa.AVATAR]), "72")
m.Push(kit.MDB_NAME, value[kit.MDB_NAME]) m.Push(kit.MDB_NAME, value[kit.MDB_NAME])

View File

@ -192,7 +192,7 @@ var Index = &ice.Context{Name: TMUX, Help: "工作台",
m.Cmdy(cli.SYSTEM, TMUX, "link-window", "-s", name, "-t", "miss:") m.Cmdy(cli.SYSTEM, TMUX, "link-window", "-s", name, "-t", "miss:")
} }
m.Option(ice.MSG_PROCESS, "_refresh") m.ProcessRefresh("1ms")
}}, }},
mdb.MODIFY: {Name: "modify", Help: "编辑", Hand: func(m *ice.Message, arg ...string) { mdb.MODIFY: {Name: "modify", Help: "编辑", Hand: func(m *ice.Message, arg ...string) {
switch arg[0] { switch arg[0] {

View File

@ -24,7 +24,6 @@ func init() {
m.Option(mdb.FIELDS, mdb.DETAIL) m.Option(mdb.FIELDS, mdb.DETAIL)
} else { } else {
m.Option(mdb.FIELDS, m.Conf(SYNC, kit.META_FIELD)) m.Option(mdb.FIELDS, m.Conf(SYNC, kit.META_FIELD))
m.Option(ice.MSG_CONTROL, ice.CONTROL_PAGE)
} }
m.Cmdy(mdb.SELECT, m.Prefix(SYNC), "", mdb.LIST, kit.MDB_ID, arg) m.Cmdy(mdb.SELECT, m.Prefix(SYNC), "", mdb.LIST, kit.MDB_ID, arg)

View File

@ -1,8 +1,6 @@
package ice package ice
import ( import (
kit "github.com/shylinux/toolkits"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io" "io"
@ -15,6 +13,8 @@ import (
"sync" "sync"
"sync/atomic" "sync/atomic"
"time" "time"
kit "github.com/shylinux/toolkits"
) )
type Cache struct { type Cache struct {