1
0
forked from x/icebergs

add tcp.server

This commit is contained in:
shaoying 2020-09-27 01:09:32 +08:00
parent fc6517d83f
commit 76fce2d013
42 changed files with 1190 additions and 871 deletions

View File

@ -16,8 +16,6 @@ const ( // 角色操作
White = "white"
Black = "black"
Right = "right"
Prune = "prune"
Clear = "clear"
)
const ( // 返回结果
OK = "ok"

View File

@ -147,7 +147,7 @@ var Index = &ice.Context{Name: "cli", Help: "命令模块",
}
})
case "ifconfig":
m.Cmdy("tcp.ip")
m.Cmdy("tcp.host")
case "userinfo":
m.Split(m.Cmdx(SYSTEM, "who"), "user term time", " ", "\n")

View File

@ -34,10 +34,10 @@ func _daemon_show(m *ice.Message, cmd *exec.Cmd, out, err string) {
h := m.Rich(DAEMON, nil, kit.Dict(
kit.MDB_TYPE, "shell", kit.MDB_NAME, strings.Join(cmd.Args, " "),
kit.MDB_DIR, cmd.Dir, kit.MDB_PID, cmd.Process.Pid, kit.MDB_STATUS, StatusStart,
kit.SSH_DIR, cmd.Dir, kit.SSH_PID, cmd.Process.Pid, kit.MDB_STATUS, StatusStart,
kit.MDB_EXTRA, kit.Dict(CMD_STDOUT, out, CMD_STDERR, err),
))
m.Log_EXPORT(kit.MDB_META, DAEMON, kit.MDB_KEY, h, kit.MDB_PID, cmd.Process.Pid)
m.Log_EXPORT(kit.MDB_META, DAEMON, kit.MDB_KEY, h, kit.SSH_PID, cmd.Process.Pid)
m.Echo("%d", cmd.Process.Pid)
m.Gos(m, func(m *ice.Message) {
@ -73,7 +73,7 @@ func init() {
}},
"prune": {Name: "prune", Help: "清理", Hand: func(m *ice.Message, arg ...string) {
m.Richs(DAEMON, "", kit.MDB_FOREACH, func(key string, value map[string]interface{}) {
if value["status"] == "error" || strings.Count(m.Cmdx(SYSTEM, "ps", value[kit.MDB_PID]), "\n") == 1 {
if value["status"] == "error" || strings.Count(m.Cmdx(SYSTEM, "ps", value[kit.SSH_PID]), "\n") == 1 {
m.Conf(DAEMON, kit.Keys(kit.MDB_HASH, key), "")
m.Log_DELETE(DAEMON, kit.Format(value))
}
@ -81,8 +81,8 @@ func init() {
}},
"stop": {Name: "stop", Help: "停止", Hand: func(m *ice.Message, arg ...string) {
m.Richs(DAEMON, "", m.Option(kit.MDB_HASH), func(key string, value map[string]interface{}) {
m.Cmdy(SYSTEM, "kill", "-9", value[kit.MDB_PID])
if strings.Count(m.Cmdx(SYSTEM, "ps", value[kit.MDB_PID]), "\n") == 1 {
m.Cmdy(SYSTEM, "kill", "-9", value[kit.SSH_PID])
if strings.Count(m.Cmdx(SYSTEM, "ps", value[kit.SSH_PID]), "\n") == 1 {
value[kit.MDB_STATUS] = StatusClose
}
})

View File

@ -248,17 +248,32 @@ func _list_inputs(m *ice.Message, prefix, chain string, field, value string) {
}
func _zone_select(m *ice.Message, prefix, chain, zone string, id string) {
cb := m.Optionv("cache.cb")
fields := kit.Split(kit.Select("zone,id,time,type,name,text", m.Option(FIELDS)))
m.Richs(prefix, chain, kit.Select(kit.MDB_FOREACH, zone), func(key string, val map[string]interface{}) {
if val[kit.MDB_META] != nil {
val = val[kit.MDB_META].(map[string]interface{})
}
if zone == "" {
m.Push(key, val, fields)
return
}
m.Grows(prefix, kit.Keys(chain, kit.MDB_HASH, key), kit.MDB_ID, id, func(index int, value map[string]interface{}) {
if value[kit.MDB_META] != nil {
value = value[kit.MDB_META].(map[string]interface{})
}
m.Push(zone, value, fields, val)
switch cb := cb.(type) {
case func(string, map[string]interface{}, map[string]interface{}):
cb(key, value, val)
default:
if len(fields) == 1 && fields[0] == DETAIL {
m.Push(DETAIL, value)
break
}
m.Push(key, value, fields, val)
}
})
})
@ -450,7 +465,7 @@ var Index = &ice.Context{Name: "mdb", Help: "数据模块",
func init() {
ice.Index.Register(Index, nil,
INSERT, DELETE, SELECT, MODIFY,
INSERT, DELETE, MODIFY, SELECT,
EXPORT, IMPORT, PRUNES, INPUTS,
PLUGIN, RENDER, SEARCH, ENGINE,
)

71
base/ssh/_trash.go Normal file
View File

@ -0,0 +1,71 @@
package ssh
func (f *Frame) history(m *ice.Message, line string) string {
favor := m.Conf(SOURCE, kit.Keys(kit.MDB_META, web.FAVOR))
if strings.HasPrefix(strings.TrimSpace(line), "!!") {
if len(line) == 2 {
line = m.Cmd(web.FAVOR, favor).Append(kit.MDB_TEXT)
}
} else if strings.HasPrefix(strings.TrimSpace(line), "!") {
if len(line) == 1 {
// 历史记录
msg := m.Cmd(web.FAVOR, favor)
msg.Sort(kit.MDB_ID)
msg.Appendv(ice.MSG_APPEND, kit.MDB_TIME, kit.MDB_ID, kit.MDB_TEXT)
f.printf(m, msg.Table().Result())
return ""
}
if i, e := strconv.Atoi(line[1:]); e == nil {
// 历史命令
line = kit.Format(kit.Value(m.Cmd(web.FAVOR, favor, i).Optionv("value"), kit.MDB_TEXT))
} else {
f.printf(m, m.Cmd("history", "search", line[1:]).Table().Result())
return ""
}
} else if strings.TrimSpace(line) != "" && f.source == STDIO {
// 记录历史
m.Cmd(web.FAVOR, favor, "cmd", f.source, line)
}
return line
}
const (
REMOTE = "remote"
QRCODE = "qrcode"
)
func init() {
Index.Merge(&ice.Context{
Configs: map[string]*ice.Config{
REMOTE: {Name: "remote", Help: "远程连接", Value: kit.Data()},
},
Commands: map[string]*ice.Command{
QRCODE: {Name: "qrcode arg...", Help: "命令提示", Action: map[string]*ice.Action{
"json": {Name: "json [key val]...", Help: "json", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(cli.PYTHON, QRCODE, kit.Format(kit.Parse(nil, "", arg...)))
m.Render(ice.RENDER_RESULT)
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Cmdy(cli.PYTHON, QRCODE, strings.Join(arg, ""))
m.Render(ice.RENDER_RESULT)
}},
REMOTE: {Name: "remote user remote port local", Help: "远程连接", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
key := m.Rich(REMOTE, nil, kit.Dict(
"user", arg[0], "remote", arg[1], "port", arg[2], "local", arg[3],
))
m.Echo(key)
m.Info(key)
m.Gos(m, func(m *ice.Message) {
for {
m.Cmd(cli.SYSTEM, "ssh", "-CNR", kit.Format("%s:%s:22", arg[2], kit.Select("localhost", arg, 3)),
kit.Format("%s@%s", arg[0], arg[1]))
m.Info("reconnect after 10s")
time.Sleep(time.Second * 10)
}
})
}},
},
}, nil)
}

View File

@ -184,17 +184,12 @@ func _ssh_handle(m *ice.Message, meta map[string]string, c net.Conn, channel ssh
request.Reply(true, nil)
}
}
func _ssh_listen(m *ice.Message, hostport string) {
func _ssh_listen(m *ice.Message, l net.Listener, hostport string) {
h := m.Cmdx(mdb.INSERT, m.Prefix(LISTEN), "", mdb.HASH, aaa.HOSTPORT, hostport, kit.MDB_STATUS, "listen")
defer m.Cmd(mdb.MODIFY, m.Prefix(LISTEN), "", mdb.HASH, kit.MDB_HASH, h, kit.MDB_STATUS, "close")
config := _ssh_config(m)
l, e := net.Listen("tcp", hostport)
m.Assert(e)
defer l.Close()
m.Logs(LISTEN, ADDRESS, l.Addr())
for {
c, e := l.Accept()
if m.Warn(e != nil, e) {
@ -248,7 +243,7 @@ func _ssh_config(m *ice.Message) *ssh.ServerConfig {
},
PublicKeyCallback: func(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) {
meta, res := map[string]string{"username": conn.User()}, errors.New(ice.ErrNotAuth)
if tcp.IPIsLocal(m, strings.Split(conn.RemoteAddr().String(), ":")[0]) {
if tcp.IsLocalHost(m, strings.Split(conn.RemoteAddr().String(), ":")[0]) {
m.Log_AUTH(aaa.HOSTPORT, conn.RemoteAddr(), aaa.USERNAME, conn.User())
res = nil
} else {
@ -382,8 +377,13 @@ func init() {
}},
LISTEN: {Name: "listen hash=auto auto", Help: "服务", Action: map[string]*ice.Action{
mdb.CREATE: {Name: "create port=9030", Help: "启动", Hand: func(m *ice.Message, arg ...string) {
m.Gos(m, func(m *ice.Message) { _ssh_listen(m, ":"+m.Option("port")) })
mdb.CREATE: {Name: "create name=tcp port=9030", Help: "启动", Hand: func(m *ice.Message, arg ...string) {
m.Option(tcp.LISTEN_CB, func(l net.Listener) {
_ssh_listen(m, l, ":"+m.Option("port"))
})
m.Gos(m, func(m *ice.Message) {
m.Cmdy(tcp.SERVER, tcp.LISTEN, kit.MDB_NAME, "ssh", tcp.PORT, m.Option(tcp.PORT))
})
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if m.Option(mdb.FIELDS, m.Conf(LISTEN, kit.META_FIELD)); len(arg) > 0 {

View File

@ -5,7 +5,6 @@ import (
"github.com/shylinux/icebergs/base/aaa"
"github.com/shylinux/icebergs/base/cli"
"github.com/shylinux/icebergs/base/mdb"
"github.com/shylinux/icebergs/base/web"
kit "github.com/shylinux/toolkits"
"bufio"
@ -14,48 +13,33 @@ import (
"io"
"os"
"path"
"strconv"
"strings"
"time"
)
type Frame struct {
source string
target *ice.Context
stdout io.Writer
count int
ps1 []string
ps2 []string
exit bool
}
func Render(msg *ice.Message, cmd string, args ...interface{}) {
defer func() { msg.Log_EXPORT(mdb.RENDER, cmd, kit.MDB_TEXT, args) }()
switch arg := kit.Simple(args...); cmd {
case ice.RENDER_OUTPUT:
case ice.RENDER_DOWNLOAD:
os.Link(kit.Select(path.Base(arg[0]), arg, 2), arg[0])
case ice.RENDER_VOID:
case ice.RENDER_RESULT:
fmt.Fprintf(msg.O, msg.Result())
case ice.RENDER_QRCODE:
if len(args) > 0 {
fmt.Println(msg.Cmdx("cli.python", "qrcode", kit.Format(args[0], args[1:]...)))
} else {
fmt.Println(msg.Cmdx("cli.python", "qrcode", kit.Format(kit.Dict(
kit.MDB_TYPE, "cmd", kit.MDB_NAME, msg.Option("_cmd"), kit.MDB_TEXT, strings.TrimSpace(msg.Result()),
))))
fmt.Fprintf(msg.O, msg.Cmdx(cli.PYTHON, "qrcode", kit.Format(args[0], args[1:]...)))
case ice.RENDER_DOWNLOAD:
if f, e := os.Open(arg[0]); e == nil {
defer f.Close()
io.Copy(msg.O, f)
}
default:
// 转换结果
res := msg.Result()
if res == "" {
res = msg.Table(nil).Result()
res = msg.Table().Result()
}
args = append(args, "length:", len(res))
@ -64,9 +48,13 @@ func Render(msg *ice.Message, cmd string, args ...interface{}) {
fmt.Fprintf(msg.O, "\n")
}
}
msg.Append(ice.MSG_OUTPUT, ice.RENDER_OUTPUT)
}
func _ssh_script(m *ice.Message, name string) io.Reader {
func Script(m *ice.Message, name string) io.Reader {
if b, ok := ice.BinPack[name]; ok {
m.Debug("binpack %v %v", len(b), name)
return bytes.NewReader(b)
}
if strings.Contains(m.Option("_script"), "/") {
name = path.Join(path.Dir(m.Option("_script")), name)
}
@ -95,42 +83,19 @@ func _ssh_script(m *ice.Message, name string) io.Reader {
}
return nil
}
func (f *Frame) history(m *ice.Message, line string) string {
favor := m.Conf(SOURCE, kit.Keys(kit.MDB_META, web.FAVOR))
if strings.HasPrefix(strings.TrimSpace(line), "!!") {
if len(line) == 2 {
line = m.Cmd(web.FAVOR, favor).Append(kit.MDB_TEXT)
}
} else if strings.HasPrefix(strings.TrimSpace(line), "!") {
if len(line) == 1 {
// 历史记录
msg := m.Cmd(web.FAVOR, favor)
msg.Sort(kit.MDB_ID)
msg.Appendv(ice.MSG_APPEND, kit.MDB_TIME, kit.MDB_ID, kit.MDB_TEXT)
f.printf(m, msg.Table().Result())
return ""
}
if i, e := strconv.Atoi(line[1:]); e == nil {
// 历史命令
line = kit.Format(kit.Value(m.Cmd(web.FAVOR, favor, i).Optionv("value"), kit.MDB_TEXT))
} else {
f.printf(m, m.Cmd("history", "search", line[1:]).Table().Result())
return ""
}
} else if strings.TrimSpace(line) != "" && f.source == STDIO {
// 记录历史
m.Cmd(web.FAVOR, favor, "cmd", f.source, line)
}
return line
}
func (f *Frame) printf(m *ice.Message, res string, arg ...interface{}) *Frame {
if len(arg) > 0 {
fmt.Fprintf(f.stdout, res, arg...)
} else {
fmt.Fprint(f.stdout, res)
}
return f
type Frame struct {
source string
target *ice.Context
stdout io.Writer
count int
ps1 []string
ps2 []string
exit bool
}
func (f *Frame) prompt(m *ice.Message, list ...string) *Frame {
if f.source != STDIO {
return f
@ -143,7 +108,7 @@ func (f *Frame) prompt(m *ice.Message, list ...string) *Frame {
for _, v := range list {
switch v {
case "count":
fmt.Fprintf(f.stdout, "%d", kit.Int(m.Conf("history", "meta.count"))+1)
fmt.Fprintf(f.stdout, "%d", f.count+1)
case "time":
fmt.Fprintf(f.stdout, time.Now().Format("15:04:05"))
case "target":
@ -154,21 +119,30 @@ func (f *Frame) prompt(m *ice.Message, list ...string) *Frame {
}
return f
}
func (f *Frame) printf(m *ice.Message, res string, arg ...interface{}) *Frame {
if len(arg) > 0 {
fmt.Fprintf(f.stdout, res, arg...)
} else {
fmt.Fprint(f.stdout, res)
}
return f
}
func (f *Frame) option(m *ice.Message, ls []string) []string {
// 解析选项
ln := []string{}
m.Option("cache.limit", 10)
for i := 0; i < len(ls); i++ {
if ls[i] == "--" {
ln = append(ln, ls[i+1:]...)
break
} else if strings.HasPrefix(ls[i], "-") {
}
if strings.HasPrefix(ls[i], "-") {
for j := i; j < len(ls); j++ {
if j == len(ls)-1 || strings.HasPrefix(ls[j+1], "-") {
if i == j {
m.Option(ls[i][1:], "true")
} else {
if i < j {
m.Option(ls[i][1:], ls[i+1:j+1])
} else {
m.Option(ls[i][1:], "true")
}
i = j
break
@ -201,7 +175,6 @@ func (f *Frame) change(m *ice.Message, ls []string) []string {
return ls
}
func (f *Frame) alias(m *ice.Message, ls []string) []string {
// 命令替换
if alias, ok := m.Optionv(ice.MSG_ALIAS).(map[string]interface{}); ok {
if len(ls) > 0 {
if a := kit.Simple(alias[ls[0]]); len(a) > 0 {
@ -212,26 +185,23 @@ func (f *Frame) alias(m *ice.Message, ls []string) []string {
return ls
}
func (f *Frame) parse(m *ice.Message, line string) string {
if strings.HasPrefix(line, "<") {
fmt.Fprintf(m.O, line)
return ""
}
for _, one := range kit.Split(line, ";", ";", ";") {
m.Log_IMPORT("stdin", one, "length", len(one))
async, one := false, strings.TrimSpace(one)
if strings.TrimSuffix(one, "&") != one {
async, one = true, strings.TrimSuffix(one, "&")
}
ls := kit.Split(one)
if m.Option("scan_mode") == "scan" {
f.printf(m, ls[0])
f.printf(m, "`")
f.printf(m, strings.Join(ls[1:], "` `"))
f.printf(m, "`")
f.printf(m, "\n")
continue
}
// 解析引擎
msg := m.Spawns(f.target)
msg.Option("_cmd", one)
ls := kit.Split(one)
ls = f.alias(msg, ls)
ls = f.change(msg, ls)
ls = f.option(msg, ls)
@ -240,15 +210,15 @@ func (f *Frame) parse(m *ice.Message, line string) string {
}
if async {
m.Debug("async %v", ls)
go msg.Cmd(ls[0], ls[1:])
msg.Gos(msg, func(msg *ice.Message) { msg.Cmd(ls[0], ls[1:]) })
continue
} else {
msg.Cmdy(ls[0], ls[1:])
}
if strings.HasPrefix(line, "<") {
msg.Resultv(line)
} else if msg.Cmdy(ls[0], ls[1:]); strings.HasPrefix(msg.Result(), "warn: ") && m.Option("render") == "raw" {
msg.Resultv(line)
if strings.HasPrefix(msg.Result(), ice.ErrWarn) && m.Option("render") == "raw" {
fmt.Fprintf(msg.O, line)
continue
}
// 渲染引擎
@ -257,7 +227,7 @@ func (f *Frame) parse(m *ice.Message, line string) string {
}
return ""
}
func (f *Frame) scan(m *ice.Message, file, line string, r io.Reader) *Frame {
func (f *Frame) scan(m *ice.Message, line string, r io.Reader) *Frame {
m.Option("ssh.return", func() { f.exit = true })
f.ps1 = kit.Simple(m.Confv("prompt", "meta.PS1"))
f.ps2 = kit.Simple(m.Confv("prompt", "meta.PS2"))
@ -267,30 +237,26 @@ func (f *Frame) scan(m *ice.Message, file, line string, r io.Reader) *Frame {
bio := bufio.NewScanner(r)
for f.prompt(m, ps...); bio.Scan() && !f.exit; f.prompt(m, ps...) {
if len(bio.Text()) == 0 {
// 空行
continue
continue // 空行
}
if strings.HasSuffix(bio.Text(), "\\") {
// 续行
line += bio.Text()[:len(bio.Text())-1]
ps = f.ps2
continue
continue // 续行
}
if line += bio.Text(); strings.Count(line, "`")%2 == 1 {
// 多行
line += "\n"
ps = f.ps2
continue
continue // 多行
}
if strings.HasPrefix(strings.TrimSpace(line), "#") {
// 注释
line = ""
continue
}
if line = f.history(m, line); line == "" {
// 历史命令
continue
continue // 注释
}
// if line = f.history(m, line); line == "" {
// // 历史命令
// continue
// }
if ps = f.ps1; f.stdout == os.Stdout {
// 清空格式
f.printf(m, "\033[0m")
@ -307,82 +273,62 @@ func (f *Frame) Spawn(m *ice.Message, c *ice.Context, arg ...string) ice.Server
return &Frame{}
}
func (f *Frame) Start(m *ice.Message, arg ...string) bool {
f.source, f.target = kit.Select(STDIO, arg, 0), m.Target()
var r io.Reader
switch kit.Select(STDIO, arg, 0) {
case STDIO:
// 终端交互
f.source = STDIO
switch m.Cap(ice.CTX_STREAM, f.source) {
case STDIO: // 终端交互
r, f.stdout = os.Stdin, os.Stdout
m.Cap(ice.CTX_STREAM, STDIO)
f.target = m.Target()
m.Option("_option", ice.MSG_USERNAME)
m.Option(ice.MSG_USERNAME, cli.UserName)
m.Option(ice.MSG_USERROLE, aaa.ROOT)
m.Option(ice.MSG_USERZONE, "boot")
aaa.UserRoot(m)
default:
if strings.HasPrefix(arg[0], "/dev") {
// 脚本解析
f.target = m.Source()
if strings.HasPrefix(f.source, "/dev") {
r, f.stdout = m.I, m.O
f.source, f.target = STDIO, m.Source()
m.Cap(ice.CTX_STREAM, STDIO)
break
}
if b, ok := ice.BinPack[arg[0]]; ok {
m.Debug("binpack %v %v", arg[0], len(b))
buf := bytes.NewBuffer(make([]byte, 0, 4096))
defer func() { m.Echo(buf.String()) }()
// 脚本解析
f.source = arg[0]
r, f.stdout = bytes.NewReader(b), buf
m.Cap(ice.CTX_STREAM, arg[0])
f.target = m.Source()
break
}
s := _ssh_script(m, arg[0])
if s == nil {
return true
}
buf := bytes.NewBuffer(make([]byte, 0, 4096))
defer func() { m.Echo(buf.String()) }()
// 脚本解析
r, f.stdout = s, buf
f.source, f.target = arg[0], m.Source()
m.Cap(ice.CTX_STREAM, arg[0])
if s := Script(m, f.source); s != nil {
r, f.stdout = s, buf
break
}
return true
}
f.scan(m, kit.Select(STDIO, arg, 0), "", r)
f.scan(m, "", r)
return true
}
func (f *Frame) Close(m *ice.Message, arg ...string) bool {
return true
}
const (
STDIO = "stdio"
)
const (
SOURCE = "source"
TARGET = "target"
PROMPT = "prompt"
QRCODE = "qrcode"
RETURN = "return"
REMOTE = "remote"
)
const (
STDIO = "stdio"
)
const SSH = "ssh"
var Index = &ice.Context{Name: "ssh", Help: "终端模块",
var Index = &ice.Context{Name: SSH, Help: "终端模块",
Configs: map[string]*ice.Config{
SOURCE: {Name: "prompt", Help: "命令提示", Value: kit.Data(
web.FAVOR, "cmd.history",
)},
PROMPT: {Name: "prompt", Help: "命令提示", Value: kit.Data(
SOURCE: {Name: SOURCE, Help: "加载脚本", Value: kit.Data()},
PROMPT: {Name: PROMPT, Help: "命令提示", Value: kit.Data(
"PS1", []interface{}{"\033[33;44m", "count", "[", "time", "]", "\033[5m", "target", "\033[0m", "\033[44m", ">", "\033[0m ", "\033[?25h", "\033[32m"},
"PS2", []interface{}{"count", " ", "target", "> "},
)},
REMOTE: {Name: "remote", Help: "远程连接", Value: kit.Data()},
},
Commands: map[string]*ice.Command{
ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Load() }},
@ -410,46 +356,13 @@ var Index = &ice.Context{Name: "ssh", Help: "终端模块",
f.ps1 = arg
f.prompt(m)
}},
QRCODE: {Name: "qrcode arg...", Help: "命令提示", Action: map[string]*ice.Action{
"json": {Name: "json [key val]...", Help: "json", Hand: func(m *ice.Message, arg ...string) {
val := map[string]interface{}{}
for i := 0; i < len(arg)-1; i += 2 {
kit.Value(val, arg[i], arg[i+1])
}
f := m.Target().Server().(*Frame)
f.printf(m, m.Cmdx(cli.PYTHON, "qrcode", kit.Format(val)))
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
f := m.Target().Server().(*Frame)
f.printf(m, m.Cmdx(cli.PYTHON, "qrcode", strings.Join(arg, "")))
}},
"what": {Name: "return", Help: "结束脚本", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Echo(kit.MergeURL2(m.Conf(web.SHARE, "meta.domain"), "/chat/lark/sso"))
}},
RETURN: {Name: "return", Help: "结束脚本", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
switch cb := m.Optionv("ssh.return").(type) {
case func():
cb()
}
}},
REMOTE: {Name: "remote user remote port local", Help: "远程连接", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
key := m.Rich(REMOTE, nil, kit.Dict(
"user", arg[0], "remote", arg[1], "port", arg[2], "local", arg[3],
))
m.Echo(key)
m.Info(key)
m.Gos(m, func(m *ice.Message) {
for {
m.Cmd(cli.SYSTEM, "ssh", "-CNR", kit.Format("%s:%s:22", arg[2], kit.Select("localhost", arg, 3)),
kit.Format("%s@%s", arg[0], arg[1]))
m.Info("reconnect after 10s")
time.Sleep(time.Second * 10)
}
})
}},
},
}
func init() { ice.Index.Register(Index, &Frame{}, SOURCE, QRCODE) }
func init() { ice.Index.Register(Index, &Frame{}, SOURCE, TARGET, RETURN) }

94
base/tcp/_trash.go Normal file
View File

@ -0,0 +1,94 @@
package tcp
import (
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/aaa"
"github.com/shylinux/icebergs/base/cli"
"bufio"
"net"
"net/url"
"strings"
)
func init() {
Index.Merge(&ice.Context{
Commands: map[string]*ice.Command{
"server": {Name: "server [tcp4|tcp6|udp4|udp6] addr", Help: "server", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
proto := "tcp4"
switch arg[0] {
case "tcp", "tcp4", "tcp6", "udp", "udp4", "udp6", "ip", "ip4", "ip6":
proto, arg = arg[0], arg[1:]
}
if l, e := net.Listen(proto, arg[0]); m.Assert(e) {
m.Gos(m, func(m *ice.Message) {
// 启动服务
m.Logs(ice.LOG_LISTEN, "addr", l.Addr())
for {
if c, e := l.Accept(); m.Assert(e) {
m.Gos(m.Spawns(), func(msg *ice.Message) {
// 建立连接
msg.Logs(ice.LOG_ACCEPT, "addr", c.RemoteAddr())
msg.Option(ice.MSG_USERADDR, c.RemoteAddr())
msg.Option(ice.MSG_USERNAME, "")
msg.Option(ice.MSG_USERROLE, "")
switch msg.Cmdx("check", c.RemoteAddr().String()) {
case "local":
// 本机用户
msg.Option(ice.MSG_USERNAME, msg.Conf(cli.RUNTIME, "boot.username"))
msg.Option(ice.MSG_USERROLE, msg.Cmdx(aaa.ROLE, "check", msg.Option(ice.MSG_USERNAME)))
msg.Logs(ice.LOG_AUTH, "name", msg.Option(ice.MSG_USERNAME), "role", msg.Option(ice.MSG_USERROLE))
}
cmds := []string{}
buf := bufio.NewWriter(c)
for bio := bufio.NewScanner(c); bio.Scan(); {
text := bio.Text()
msg.Logs("scan", "len", len(text), "text", text)
if len(text) == 0 {
if len(cmds) > 0 {
msg.Cmd(aaa.ROLE, "right")
// 执行命令
res := msg.Cmd(cmds)
// 返回结果
for _, str := range res.Resultv() {
buf.WriteString("result:")
buf.WriteString(url.QueryEscape(str))
buf.WriteString("\n")
}
buf.WriteString("\n")
buf.Flush()
cmds = cmds[:0]
}
continue
}
// 解析请求
line := strings.SplitN(bio.Text(), ":", 2)
line[0], e = url.QueryUnescape(line[0])
m.Assert(e)
line[1], e = url.QueryUnescape(line[1])
m.Assert(e)
switch line[0] {
case "cmds", ice.MSG_DETAIL:
cmds = append(cmds, line[1])
default:
msg.Option(line[0], line[1])
}
}
msg.Logs(ice.LOG_FINISH, "addr", c.RemoteAddr())
})
}
}
m.Logs(ice.LOG_FINISH, "addr", l.Addr())
})
}
}},
},
}, nil)
}

66
base/tcp/client.go Normal file
View File

@ -0,0 +1,66 @@
package tcp
import (
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/mdb"
kit "github.com/shylinux/toolkits"
"net"
)
const (
DIAL_CB = "dial.cb"
DIAL = "dial"
)
const CLIENT = "client"
func init() {
Index.Merge(&ice.Context{
Configs: map[string]*ice.Config{
CLIENT: {Name: CLIENT, Help: "客户端", Value: kit.Data()},
},
Commands: map[string]*ice.Command{
CLIENT: {Name: "client hash auto 连接 清理", Help: "客户端", Action: map[string]*ice.Action{
DIAL: {Name: "dial host=localhost port=9010", Help: "连接", Hand: func(m *ice.Message, arg ...string) {
c, e := net.Dial(TCP, m.Option(HOST)+":"+m.Option(PORT))
h := m.Cmdx(mdb.INSERT, CLIENT, "", mdb.HASH, HOST, m.Option(HOST), PORT, m.Option(PORT), kit.MDB_STATUS, kit.Select(ERROR, OPEN, e == nil), kit.MDB_ERROR, kit.Format(e))
c = &Conn{h: h, m: m, s: &Stat{}, Conn: c}
if e == nil {
defer c.Close()
}
switch cb := m.Optionv(DIAL_CB).(type) {
case func(net.Conn, error):
cb(c, e)
case func(net.Conn):
m.Assert(e)
cb(c)
case func(net.Conn, []byte, error):
b := make([]byte, 4096)
for {
n, e := c.Read(b)
if cb(c, b[:n], e); e != nil {
break
}
}
default:
c.Write([]byte("hello world\n"))
}
}},
mdb.DELETE: {Name: "delete", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(mdb.DELETE, CLIENT, "", 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, CLIENT, "", mdb.HASH, kit.MDB_STATUS, ERROR)
m.Cmdy(mdb.PRUNES, CLIENT, "", mdb.HASH, kit.MDB_STATUS, CLOSE)
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Option(mdb.FIELDS, kit.Select(mdb.DETAIL, "time,hash,status,host,port,error,nread,nwrite", len(arg) == 0))
m.Cmdy(mdb.SELECT, CLIENT, "", mdb.HASH, kit.MDB_HASH, arg)
m.PushAction("删除")
}},
},
}, nil)
}

86
base/tcp/host.go Normal file
View File

@ -0,0 +1,86 @@
package tcp
import (
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/aaa"
kit "github.com/shylinux/toolkits"
"net"
"strings"
)
func _host_list(m *ice.Message, ifname string) {
if ifs, e := net.Interfaces(); m.Assert(e) {
for _, v := range ifs {
if ifname != "" && !strings.Contains(v.Name, ifname) {
continue
}
if len(v.HardwareAddr.String()) == 0 {
continue
}
if ips, e := v.Addrs(); m.Assert(e) {
for _, x := range ips {
ip := strings.Split(x.String(), "/")
if strings.Contains(ip[0], ":") || len(ip) == 0 {
continue
}
m.Push("index", v.Index)
m.Push("name", v.Name)
m.Push("ip", ip[0])
m.Push("mask", ip[1])
m.Push("hard", v.HardwareAddr.String())
}
}
}
}
if len(m.Appendv("ip")) == 0 {
m.Push("index", -1)
m.Push("name", "local")
m.Push("ip", "127.0.0.1")
m.Push("mask", "255.0.0.0")
m.Push("hard", "")
}
}
func _islocalhost(m *ice.Message, ip string) (ok bool) {
if ip == "::1" || strings.HasPrefix(ip, "127.") {
return true
}
if m.Richs(HOST, kit.Keys("meta.black"), ip, nil) != nil {
return false
}
if m.Richs(HOST, kit.Keys("meta.white"), ip, nil) != nil {
m.Log_AUTH(aaa.White, ip)
return true
}
return false
}
func IsLocalHost(m *ice.Message, ip string) bool { return _islocalhost(m, ip) }
const HOST = "host"
func init() {
Index.Merge(&ice.Context{
Configs: map[string]*ice.Config{
HOST: {Name: HOST, Help: "主机", Value: kit.Data(
aaa.Black, kit.Dict(kit.MDB_SHORT, kit.MDB_TEXT),
aaa.White, kit.Data(kit.MDB_SHORT, kit.MDB_TEXT),
)},
},
Commands: map[string]*ice.Command{
HOST: {Name: "host name auto", Help: "主机", Action: map[string]*ice.Action{
aaa.White: {Name: "white", Help: "白名单", Hand: func(m *ice.Message, arg ...string) {
m.Rich(HOST, kit.Keys("meta.white"), kit.Dict(kit.MDB_NAME, "", kit.MDB_TEXT, arg[0]))
}},
aaa.Black: {Name: "black", Help: "黑名单", Hand: func(m *ice.Message, arg ...string) {
m.Rich(HOST, kit.Keys("meta.black"), kit.Dict(kit.MDB_NAME, "", kit.MDB_TEXT, arg[0]))
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
_host_list(m, kit.Select("", arg, 0))
}},
},
}, nil)
}

72
base/tcp/port.go Normal file
View File

@ -0,0 +1,72 @@
package tcp
import (
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/aaa"
"github.com/shylinux/icebergs/base/cli"
"github.com/shylinux/icebergs/base/nfs"
kit "github.com/shylinux/toolkits"
"net"
"os"
"path"
)
func _port_list(m *ice.Message, port string, dir string) {
if m.Cmdy(nfs.DIR, path.Join("var/daemon", port, dir)); port == "" {
m.Table(func(index int, value map[string]string, head []string) {
m.Push(PORT, path.Base(value["path"]))
})
}
}
func _port_right(m *ice.Message, begin string) string {
current := kit.Int(kit.Select(m.Conf(PORT, "meta.current"), begin))
end := kit.Int(m.Conf(PORT, "meta.end"))
if current >= end {
current = kit.Int(m.Conf(PORT, "meta.begin"))
}
for i := current; i < end; i++ {
if c, e := net.Dial("tcp", kit.Format(":%d", i)); e == nil {
m.Info("port exists %v", i)
defer c.Close()
continue
}
m.Log_SELECT(PORT, i)
m.Conf(PORT, "meta.current", i)
return kit.Format("%d", i)
}
return ""
}
const PORT = "port"
func init() {
Index.Merge(&ice.Context{
Configs: map[string]*ice.Config{
PORT: {Name: PORT, Help: "端口", Value: kit.Data(
"begin", 10000, "current", 10000, "end", 20000,
)},
},
Commands: map[string]*ice.Command{
PORT: {Name: "port port path auto", Help: "端口", Action: map[string]*ice.Action{
aaa.Right: {Name: "right [begin]", Help: "分配", Hand: func(m *ice.Message, arg ...string) {
port, p := kit.Select("", arg, 0), ""
for i := 0; i < 10; i++ {
port = _port_right(m, port)
p = path.Join(m.Conf(cli.DAEMON, kit.META_PATH), port)
if _, e := os.Stat(p); e != nil && os.IsNotExist(e) {
os.MkdirAll(p, ice.MOD_DIR)
break
}
port = kit.Format(kit.Int(port) + 1)
}
m.Echo(port)
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
_port_list(m, kit.Select("", arg, 0), kit.Select("", arg, 1))
}},
},
}, nil)
}

149
base/tcp/server.go Normal file
View File

@ -0,0 +1,149 @@
package tcp
import (
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/mdb"
kit "github.com/shylinux/toolkits"
"net"
"strings"
)
type Stat struct {
nc, nr, nw int
}
type Conn struct {
h string
m *ice.Message
s *Stat
net.Conn
}
func (c *Conn) Read(b []byte) (int, error) {
n, e := c.Conn.Read(b)
c.s.nr += n
c.m.Conf(CLIENT, kit.Keys(kit.MDB_HASH, c.h, kit.MDB_META, "nwrite"), c.s.nw)
return n, e
}
func (c *Conn) Write(b []byte) (int, error) {
n, e := c.Conn.Write(b)
c.s.nw += n
c.m.Conf(CLIENT, kit.Keys(kit.MDB_HASH, c.h, kit.MDB_META, "nread"), c.s.nr)
return n, e
}
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)
return c.Conn.Close()
}
type Listener struct {
h string
m *ice.Message
s *Stat
net.Listener
}
func (l Listener) Accept() (net.Conn, error) {
c, e := l.Listener.Accept()
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_STATUS, kit.Select(ERROR, OPEN, e == nil), kit.MDB_ERROR, kit.Format(e))
c = &Conn{h: h, m: l.m, s: &Stat{}, Conn: c}
return c, e
}
func (l Listener) Close() error {
l.m.Cmd(mdb.MODIFY, SERVER, "", mdb.HASH, kit.MDB_HASH, l.h, kit.MDB_STATUS, CLOSE)
return l.Listener.Close()
}
const (
OPEN = "open"
CLOSE = "close"
ERROR = "error"
)
const (
LISTEN_CB = "listen.cb"
LISTEN = "listen"
)
const SERVER = "server"
func init() {
Index.Merge(&ice.Context{
Configs: map[string]*ice.Config{
SERVER: {Name: SERVER, Help: "服务器", Value: kit.Data()},
},
Commands: map[string]*ice.Command{
SERVER: {Name: "server hash auto 监听 清理", Help: "服务器", Action: map[string]*ice.Action{
LISTEN: {Name: "LISTEN host=localhost port=9010", Help: "监听", Hand: func(m *ice.Message, arg ...string) {
l, e := net.Listen(TCP, m.Option(HOST)+":"+m.Option(PORT))
h := m.Option(kit.MDB_HASH)
if h == "" {
h = m.Cmdx(mdb.INSERT, SERVER, "", mdb.HASH, kit.MDB_NAME, m.Option(kit.MDB_NAME), HOST, m.Option(HOST), PORT, m.Option(PORT), kit.MDB_STATUS, kit.Select(ERROR, OPEN, e == nil), kit.MDB_ERROR, kit.Format(e))
}
l = &Listener{h: h, m: m, s: &Stat{}, Listener: l}
if e == nil {
defer l.Close()
}
switch cb := m.Optionv(LISTEN_CB).(type) {
case func(net.Listener, error):
cb(l, e)
case func(net.Listener):
m.Assert(e)
cb(l)
case func(net.Conn):
for {
c, e := l.Accept()
if cb(c); e != nil {
break
}
}
case func(net.Conn, error):
for {
c, e := l.Accept()
if cb(c, e); e != nil {
break
}
}
default:
for {
c, e := l.Accept()
if e == nil {
b := make([]byte, 1024)
if n, e := c.Read(b); e == nil {
m.Info("nonce", string(b[:n]))
c.Write(b[:n])
}
} else {
break
}
c.Close()
}
}
}},
mdb.DELETE: {Name: "delete", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(mdb.DELETE, SERVER, "", 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, SERVER, "", mdb.HASH, kit.MDB_STATUS, ERROR)
m.Cmdy(mdb.PRUNES, SERVER, "", mdb.HASH, kit.MDB_STATUS, CLOSE)
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Option(mdb.FIELDS, kit.Select(mdb.DETAIL, "time,hash,status,name,host,port,error,nconn", len(arg) == 0))
m.Cmdy(mdb.SELECT, SERVER, "", mdb.HASH, kit.MDB_HASH, arg)
m.PushAction("删除")
}},
},
}, nil)
}

View File

@ -1,215 +1,31 @@
package tcp
import (
"os"
"path"
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/aaa"
"github.com/shylinux/icebergs/base/cli"
kit "github.com/shylinux/toolkits"
"bufio"
"net"
"net/url"
"strings"
)
func _port_list(m *ice.Message) string {
return ""
}
func _port_get(m *ice.Message, begin string) string {
current := kit.Int(kit.Select(m.Conf(PORT, "meta.current"), begin))
end := kit.Int(m.Conf(PORT, "meta.end"))
if current >= end {
current = kit.Int(m.Conf(PORT, "meta.begin"))
}
for i := current; i < end; i++ {
if c, e := net.Dial("tcp", kit.Format(":%d", i)); e == nil {
m.Info("port exists %v", i)
defer c.Close()
continue
}
m.Conf(PORT, "meta.current", i)
m.Log_SELECT(PORT, i)
return kit.Format("%d", i)
}
return ""
}
const TCP = "tcp"
func _ip_list(m *ice.Message, ifname string) {
if ifs, e := net.Interfaces(); m.Assert(e) {
for _, v := range ifs {
if ifname != "" && !strings.Contains(v.Name, ifname) {
continue
}
if ips, e := v.Addrs(); m.Assert(e) {
for _, x := range ips {
ip := strings.Split(x.String(), "/")
if strings.Contains(ip[0], ":") || len(ip) == 0 {
continue
}
if len(v.HardwareAddr.String()) == 0 {
continue
}
m.Push("index", v.Index)
m.Push("name", v.Name)
m.Push("ip", ip[0])
m.Push("mask", ip[1])
m.Push("hard", v.HardwareAddr.String())
}
}
}
}
}
func _ip_islocal(m *ice.Message, ip string) (ok bool) {
if ip == "::1" || strings.HasPrefix(ip, "127.") {
return true
}
if m.Richs(IP, kit.Keys("meta.white"), ip, nil) == nil {
return false
}
m.Log_AUTH(aaa.White, ip)
return true
}
func IPIsLocal(m *ice.Message, ip string) bool {
return _ip_islocal(m, ip)
}
const (
IP = "ip"
PORT = "port"
)
var Index = &ice.Context{Name: "tcp", Help: "通信模块",
Configs: map[string]*ice.Config{
PORT: {Name: "port", Help: "端口", Value: kit.Data(
"begin", 10000, "current", 10000, "end", 20000,
)},
IP: {Name: "ip", Help: "地址", Value: kit.Data(
"black", kit.Dict(),
"white", kit.Data(kit.MDB_SHORT, kit.MDB_TEXT),
)},
},
var Index = &ice.Context{Name: TCP, Help: "通信模块",
Commands: map[string]*ice.Command{
ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Load()
m.Cmd(IP).Table(func(index int, value map[string]string, head []string) {
m.Cmd(IP, aaa.White, value[IP])
m.Cmd(HOST).Table(func(index int, value map[string]string, head []string) {
m.Cmd(HOST, aaa.White, value["ip"])
})
}},
ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Save(PORT) }},
IP: {Name: "ip", Help: "地址", Action: map[string]*ice.Action{
aaa.White: {Name: "show ip", Help: "白名单", Hand: func(m *ice.Message, arg ...string) {
m.Rich(IP, kit.Keys("meta.white"), kit.Dict(
kit.MDB_NAME, "",
kit.MDB_TEXT, arg[0],
))
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
_ip_list(m, "")
}},
PORT: {Name: "port", Help: "端口", Action: map[string]*ice.Action{
"get": {Name: "get", Help: "分配端口", Hand: func(m *ice.Message, arg ...string) {
m.Echo(_port_get(m, ""))
}},
"select": {Name: "select [begin]", Help: "分配端口", Hand: func(m *ice.Message, arg ...string) {
port, p := kit.Select("", arg, 0), ""
for i := 0; i < 10; i++ {
port = _port_get(m, port)
p = path.Join(m.Conf(cli.DAEMON, kit.META_PATH), port)
if _, e := os.Stat(p); e != nil && os.IsNotExist(e) {
break
}
port = kit.Format(kit.Int(port) + 1)
}
os.MkdirAll(p, ice.MOD_DIR)
m.Echo(port)
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
_port_list(m)
}},
"server": {Name: "server [tcp4|tcp6|udp4|udp6] addr", Help: "server", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
proto := "tcp4"
switch arg[0] {
case "tcp", "tcp4", "tcp6", "udp", "udp4", "udp6", "ip", "ip4", "ip6":
proto, arg = arg[0], arg[1:]
}
if l, e := net.Listen(proto, arg[0]); m.Assert(e) {
m.Gos(m, func(m *ice.Message) {
// 启动服务
m.Logs(ice.LOG_LISTEN, "addr", l.Addr())
for {
if c, e := l.Accept(); m.Assert(e) {
m.Gos(m.Spawns(), func(msg *ice.Message) {
// 建立连接
msg.Logs(ice.LOG_ACCEPT, "addr", c.RemoteAddr())
msg.Option(ice.MSG_USERADDR, c.RemoteAddr())
msg.Option(ice.MSG_USERNAME, "")
msg.Option(ice.MSG_USERROLE, "")
switch msg.Cmdx("check", c.RemoteAddr().String()) {
case "local":
// 本机用户
msg.Option(ice.MSG_USERNAME, msg.Conf(cli.RUNTIME, "boot.username"))
msg.Option(ice.MSG_USERROLE, msg.Cmdx(aaa.ROLE, "check", msg.Option(ice.MSG_USERNAME)))
msg.Logs(ice.LOG_AUTH, "name", msg.Option(ice.MSG_USERNAME), "role", msg.Option(ice.MSG_USERROLE))
}
cmds := []string{}
buf := bufio.NewWriter(c)
for bio := bufio.NewScanner(c); bio.Scan(); {
text := bio.Text()
msg.Logs("scan", "len", len(text), "text", text)
if len(text) == 0 {
if len(cmds) > 0 {
msg.Cmd(aaa.ROLE, "right")
// 执行命令
res := msg.Cmd(cmds)
// 返回结果
for _, str := range res.Resultv() {
buf.WriteString("result:")
buf.WriteString(url.QueryEscape(str))
buf.WriteString("\n")
}
buf.WriteString("\n")
buf.Flush()
cmds = cmds[:0]
}
continue
}
// 解析请求
line := strings.SplitN(bio.Text(), ":", 2)
line[0], e = url.QueryUnescape(line[0])
m.Assert(e)
line[1], e = url.QueryUnescape(line[1])
m.Assert(e)
switch line[0] {
case "cmds", ice.MSG_DETAIL:
cmds = append(cmds, line[1])
default:
msg.Option(line[0], line[1])
}
}
msg.Logs(ice.LOG_FINISH, "addr", c.RemoteAddr())
})
}
}
m.Logs(ice.LOG_FINISH, "addr", l.Addr())
})
}
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{}) {
kit.Value(value, "meta.status", CLOSE)
})
m.Richs(SERVER, "", kit.MDB_FOREACH, func(key string, value map[string]interface{}) {
kit.Value(value, "meta.status", CLOSE)
})
m.Save()
}},
},
}
func init() { ice.Index.Register(Index, nil, IP, PORT) }
func init() { ice.Index.Register(Index, nil, HOST, PORT, CLIENT, SERVER) }

6
base/tcp/tcp.shy Normal file
View File

@ -0,0 +1,6 @@
chapter "tcp"
field host tcp.host
# field port tcp.port
field server tcp.server
field client tcp.client

View File

@ -359,5 +359,45 @@ func init() {
m.Option(kit.MDB_NAME), m.Option(kit.MDB_TEXT), m.Option(kit.MDB_EXTRA))
}
}},
"/share/": {Name: "/share/", Help: "共享链", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Richs(SHARE, nil, kit.Select(m.Option(kit.SSH_SHARE), arg, 0), func(key string, value map[string]interface{}) {
m.Log_SELECT(kit.MDB_META, SHARE, "arg", arg, "value", kit.Format(value))
if m.Warn(m.Option(ice.MSG_USERROLE) != aaa.ROOT && kit.Time(kit.Format(value[kit.MDB_TIME])) < kit.Time(m.Time()), "expired") {
m.Echo("expired")
return
}
switch value[kit.MDB_TYPE] {
case STORY:
value = _share_story(m, value, arg...)
}
if _share_show(m, key, value, kit.Select("", arg, 1), kit.Select("", arg, 2)) {
return
}
switch value[kit.MDB_TYPE] {
case TYPE_RIVER:
// 共享群组
m.Render("redirect", "/", "share", key, "river", kit.Format(value["text"]))
case TYPE_STORM:
// 共享应用
m.Render("redirect", "/", "share", key, "storm", kit.Format(value["text"]), "river", kit.Format(kit.Value(value, "extra.river")))
case TYPE_ACTION:
_share_action(m, value, arg...)
default:
// 查看数据
m.Option(kit.MDB_VALUE, value)
m.Option(kit.MDB_TYPE, value[kit.MDB_TYPE])
m.Option(kit.MDB_NAME, value[kit.MDB_NAME])
m.Option(kit.MDB_TEXT, value[kit.MDB_TEXT])
m.Render(ice.RENDER_TEMPLATE, m.Conf(SHARE, "meta.template.simple"))
m.Option(ice.MSG_OUTPUT, ice.RENDER_RESULT)
}
})
}},
}}, nil)
}

201
base/web/_share.go Normal file
View File

@ -0,0 +1,201 @@
package web
import (
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/aaa"
"github.com/shylinux/icebergs/base/cli"
"github.com/shylinux/icebergs/base/ctx"
"github.com/shylinux/icebergs/base/mdb"
kit "github.com/shylinux/toolkits"
"fmt"
"net/http"
"os"
"path"
"strings"
"time"
)
func _share_list(m *ice.Message, key string, fields ...string) {
if key == "" {
m.Grows(SHARE, nil, "", "", func(index int, value map[string]interface{}) {
m.Push("", value, []string{kit.MDB_TIME, kit.SSH_SHARE, kit.MDB_TYPE, kit.MDB_NAME, kit.MDB_TEXT})
m.Push(kit.MDB_LINK, fmt.Sprintf(m.Conf(SHARE, "meta.template.link"), m.Conf(SHARE, "meta.domain"), value[kit.SSH_SHARE], value[kit.SSH_SHARE]))
})
return
}
m.Richs(SHARE, nil, key, func(key string, value map[string]interface{}) {
m.Push("detail", value)
m.Push(kit.MDB_KEY, kit.MDB_LINK)
m.Push(kit.MDB_VALUE, m.Cmdx(mdb.RENDER, RENDER.A, key, URL(m, kit.Format("/share/%s", key))))
m.Push(kit.MDB_KEY, kit.SSH_SHARE)
m.Push(kit.MDB_VALUE, m.Cmdx(mdb.RENDER, RENDER.IMG, URL(m, kit.Format("/share/%s/share", key))))
m.Push(kit.MDB_KEY, kit.MDB_VALUE)
m.Push(kit.MDB_VALUE, m.Cmdx(mdb.RENDER, RENDER.IMG, URL(m, kit.Format("/share/%s/value", key))))
})
}
func _share_show(m *ice.Message, key string, value map[string]interface{}, arg ...string) bool {
switch kit.Select("", arg, 0) {
case "check", "安全码":
m.Render(ice.RENDER_QRCODE, kit.Format(kit.Dict(
kit.MDB_TYPE, SHARE, kit.MDB_NAME, value[kit.MDB_TYPE], kit.MDB_TEXT, key,
)))
case kit.SSH_SHARE, "共享码":
m.Render(ice.RENDER_QRCODE, kit.Format("%s/share/%s/?share=%s", m.Conf(SHARE, "meta.domain"), key, key))
case kit.MDB_VALUE, "数据值":
m.Render(ice.RENDER_QRCODE, kit.Format(value), kit.Select("256", arg, 1))
case kit.MDB_TEXT:
m.Render(ice.RENDER_QRCODE, kit.Format(value[kit.MDB_TEXT]))
case "detail", "详情":
m.Render(kit.Formats(value))
case "download", "下载":
if strings.HasPrefix(kit.Format(value["text"]), m.Conf(CACHE, "meta.path")) {
m.Render(ice.RENDER_DOWNLOAD, value["text"], value["type"], value["name"])
} else {
m.Render("%s", value["text"])
}
default:
return false
}
return true
}
func _share_create(m *ice.Message, kind, name, text string, arg ...string) string {
h := m.Rich(SHARE, nil, kit.Dict(
kit.MDB_TIME, m.Time(m.Conf(SHARE, "meta.expire")),
kit.MDB_TYPE, kind, kit.MDB_NAME, name, kit.MDB_TEXT, text,
kit.MDB_EXTRA, kit.Dict(
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),
))
// 创建列表
m.Grow(SHARE, nil, kit.Dict(
kit.MDB_TYPE, kind, kit.MDB_NAME, name, kit.MDB_TEXT, text,
kit.SSH_SHARE, h,
))
m.Log_CREATE(kit.SSH_SHARE, h, kit.MDB_TYPE, kind, kit.MDB_NAME, name)
m.Echo(h)
return h
}
func _share_story(m *ice.Message, value map[string]interface{}, arg ...string) map[string]interface{} {
msg := m.Cmd(STORY, INDEX, value["text"])
if msg.Append("text") == "" && kit.Value(value, "extra.pod") != "" {
msg = m.Cmd(SPACE, kit.Value(value, "extra.pod"), STORY, INDEX, value["text"])
}
value = kit.Dict("type", msg.Append("scene"), "name", msg.Append("story"), "text", msg.Append("text"), "file", msg.Append("file"))
m.Log(ice.LOG_EXPORT, "%s: %v", arg, kit.Format(value))
return value
}
func _share_action(m *ice.Message, value map[string]interface{}, arg ...string) bool {
if len(arg) == 1 || arg[1] == "" {
return _share_action_redirect(m, value, arg[0])
}
if arg[1] == "" {
return _share_action_page(m, value)
}
if len(arg) == 2 {
return _share_action_list(m, value, arg[0], arg[1])
}
// 默认参数
meta := kit.Value(value, kit.Format("extra.tool.%s", arg[2])).(map[string]interface{})
if meta["single"] == "yes" && kit.Select("", arg, 3) != "action" {
arg = append(arg[:3], kit.Simple(kit.UnMarshal(kit.Format(meta["args"])))...)
for i := len(arg) - 1; i >= 0; i-- {
if arg[i] != "" {
return true
}
arg = arg[:i]
}
}
// 执行命令
cmds := kit.Simple(m.Space(meta["pod"]), kit.Keys(meta["ctx"], meta["cmd"]), arg[3:])
m.Cmdy(cmds).Option("cmds", cmds)
m.Option("title", value["name"])
if strings.HasPrefix(kit.Format(value["text"]), m.Conf(CACHE, "meta.path")) {
m.Render(ice.RENDER_DOWNLOAD, value["text"], value["type"], value["name"])
} else {
m.Render("%s", value["text"])
}
return true
}
func _share_action_redirect(m *ice.Message, value map[string]interface{}, share string) bool {
tool := kit.Value(value, "extra.tool.0").(map[string]interface{})
m.Render("redirect", "/share", "share", share, "title", kit.Format(value["name"]),
"river", kit.Format(kit.Value(value, "extra.river")),
"storm", kit.Format(kit.Value(value, "extra.storm")),
"pod", kit.Format(tool["pod"]), kit.UnMarshal(kit.Format(tool["val"])),
)
return true
}
func _share_action_page(m *ice.Message, value map[string]interface{}) bool {
Render(m, ice.RENDER_DOWNLOAD, m.Conf(SERVE, "meta.page.share"))
return true
}
func _share_action_list(m *ice.Message, value map[string]interface{}, river, storm string) bool {
value["count"] = kit.Int(value["count"]) + 1
kit.Fetch(kit.Value(value, "extra.tool"), func(index int, value map[string]interface{}) {
m.Push("river", river)
m.Push("storm", storm)
m.Push("action", index)
m.Push("node", value["pod"])
m.Push("group", value["ctx"])
m.Push("index", value["cmd"])
m.Push("args", value["args"])
m.Push("value", value["value"])
msg := m.Cmd(m.Space(value["pod"]), ctx.COMMAND, value["ctx"], value["cmd"])
ls := strings.Split(kit.Format(value["cmd"]), ".")
m.Push("name", ls[len(ls)-1])
m.Push("help", kit.Select(msg.Append("help"), kit.Format(value["help"])))
m.Push("inputs", msg.Append("list"))
m.Push("feature", msg.Append("meta"))
})
return true
}
func _share_auth(m *ice.Message, share string, role string) {
m.Richs(SHARE, nil, share, func(key string, value map[string]interface{}) {
switch value["type"] {
case "active":
m.Cmdy(SPACE, value["name"], "sessid", m.Cmdx(aaa.SESS, "create", role))
case "user":
m.Cmdy(aaa.ROLE, role, value["name"])
default:
m.Cmdy(aaa.SESS, "auth", value["text"], role)
}
})
}
func _share_check(m *ice.Message, share string) {
m.Richs(SHARE, nil, share, func(key string, value map[string]interface{}) {
m.Render(ice.RENDER_QRCODE, kit.Format(kit.Dict(
kit.MDB_TYPE, "share", kit.MDB_NAME, value["type"], kit.MDB_TEXT, key,
)))
})
}
func _trash(m *ice.Message, arg ...string) {
switch arg[0] {
case "invite":
arg = []string{arg[0], m.Cmdx(SHARE, "invite", kit.Select("tech", arg, 1), kit.Select("miss", arg, 2))}
fallthrough
case "check":
_share_check(m, arg[1])
case "auth":
_share_auth(m, arg[1], arg[2])
case "add":
_share_create(m, arg[1], arg[2], arg[3], arg[4:]...)
default:
if len(arg) == 1 {
_share_list(m, arg[0])
break
}
}
}

View File

@ -120,10 +120,10 @@ func _cache_download(m *ice.Message, r *http.Response) (file, size string) {
value = value[kit.MDB_META].(map[string]interface{})
s := size * 100 / total
if s != kit.Int(value[kit.MDB_STEP]) && s%10 == 0 {
m.Log_IMPORT(kit.MDB_FILE, path.Base(cb[2]), kit.MDB_STEP, s, kit.MDB_SIZE, kit.FmtSize(int64(size)), kit.MDB_TOTAL, kit.FmtSize(int64(total)))
if s != kit.Int(value[kit.SSH_STEP]) && s%10 == 0 {
m.Log_IMPORT(kit.MDB_FILE, path.Base(cb[2]), kit.SSH_STEP, s, kit.MDB_SIZE, kit.FmtSize(int64(size)), kit.MDB_TOTAL, kit.FmtSize(int64(total)))
}
value[kit.MDB_STEP], value[kit.MDB_SIZE], value[kit.MDB_TOTAL] = kit.Format(s), size, total
value[kit.SSH_STEP], value[kit.MDB_SIZE], value[kit.MDB_TOTAL] = kit.Format(s), size, total
})
case func(int, int):
cb(size, total)

View File

@ -99,7 +99,7 @@ ish_miss_prepare_install
Commands: map[string]*ice.Command{
DREAM: {Name: "dream [name [cmd...]] auto", Help: "梦想家", Meta: kit.Dict("detail", []interface{}{"启动", "停止"}), Action: map[string]*ice.Action{
gdb.START: {Name: "start type name", Help: "启动", Hand: func(m *ice.Message, arg ...string) {
m.Option(kit.MDB_NAME, kit.Select(path.Base(m.Option(kit.MDB_REPOS)), m.Option(kit.MDB_NAME)))
m.Option(kit.MDB_NAME, kit.Select(path.Base(m.Option(kit.SSH_REPOS)), m.Option(kit.MDB_NAME)))
_dream_show(m, m.Option(kit.MDB_NAME))
}},
gdb.STOP: {Name: "stop", Help: "停止", Hand: func(m *ice.Message, arg ...string) {

View File

@ -8,14 +8,14 @@ import (
)
func _label_add(m *ice.Message, cmd string) {
if m.Option(cmd) != "" && m.Option(kit.MDB_GROUP) != "" && m.Option(kit.MDB_NAME) != "" {
m.Cmdy(cmd, m.Option(cmd), "add", m.Option(kit.MDB_GROUP), m.Option(kit.MDB_NAME))
if m.Option(cmd) != "" && m.Option(kit.SSH_GROUP) != "" && m.Option(kit.MDB_NAME) != "" {
m.Cmdy(cmd, m.Option(cmd), "add", m.Option(kit.SSH_GROUP), m.Option(kit.MDB_NAME))
m.Option(ice.FIELD_RELOAD, "true")
}
}
func _label_del(m *ice.Message, cmd string) {
if m.Option(cmd) != "" && m.Option(kit.MDB_GROUP) != "" && m.Option(kit.MDB_NAME) != "" {
m.Cmdy(cmd, m.Option(cmd), "del", m.Option(kit.MDB_GROUP), m.Option(kit.MDB_NAME))
if m.Option(cmd) != "" && m.Option(kit.SSH_GROUP) != "" && m.Option(kit.MDB_NAME) != "" {
m.Cmdy(cmd, m.Option(cmd), "del", m.Option(kit.SSH_GROUP), m.Option(kit.MDB_NAME))
m.Option(ice.FIELD_RELOAD, "true")
}
}
@ -23,7 +23,7 @@ func _label_prune(m *ice.Message, cmd string) {
m.Richs(cmd, nil, m.Option(cmd), func(key string, value map[string]interface{}) {
m.Richs(cmd, kit.Keys(kit.MDB_HASH, key), kit.MDB_FOREACH, func(sub string, value map[string]interface{}) {
if value[kit.MDB_STATUS] != "busy" {
m.Cmdy(cmd, m.Option(cmd), "del", value[kit.MDB_GROUP], value[kit.MDB_NAME])
m.Cmdy(cmd, m.Option(cmd), "del", value[kit.SSH_GROUP], value[kit.MDB_NAME])
m.Option(ice.FIELD_RELOAD, "true")
}
})
@ -70,7 +70,7 @@ func _label_select(m *ice.Message, cmd string, arg ...string) {
if len(arg) < 2 {
// 二级列表
m.Option(ice.FIELD_DETAIL, "添加", "退还", "清理", "清空")
m.Push(key, value, []string{kit.MDB_TIME, kit.MDB_GROUP, kit.MDB_STATUS, kit.MDB_NAME})
m.Push(key, value, []string{kit.MDB_TIME, kit.SSH_GROUP, kit.MDB_STATUS, kit.MDB_NAME})
return
}
// 分组详情
@ -94,7 +94,7 @@ func _label_create(m *ice.Message, cmd string, key string, arg ...string) {
}) == nil {
m.Logs(ice.LOG_INSERT, cmd, arg[0], kit.MDB_NAME, pod)
m.Rich(cmd, kit.Keys(kit.MDB_HASH, key), kit.Dict(
kit.MDB_NAME, pod, kit.MDB_GROUP, arg[2], kit.MDB_STATUS, "free",
kit.MDB_NAME, pod, kit.SSH_GROUP, arg[2], kit.MDB_STATUS, "free",
))
}
m.Echo(arg[0])
@ -105,7 +105,7 @@ func _label_remove(m *ice.Message, cmd string, key string, arg ...string) {
if value[kit.MDB_STATUS] == "free" {
value[kit.MDB_STATUS] = "void"
m.Logs(ice.LOG_MODIFY, cmd, arg[0], kit.MDB_NAME, arg[3], kit.MDB_STATUS, "void")
m.Cmdx(GROUP, value[kit.MDB_GROUP], "put", arg[3])
m.Cmdx(GROUP, value[kit.SSH_GROUP], "put", arg[3])
m.Echo(arg[3])
}
})
@ -176,7 +176,7 @@ func init() {
if arg[0] == "route" {
m.Cmd(ROUTE).Table(func(index int, value map[string]string, field []string) {
m.Rich(cmd, kit.Keys(kit.MDB_HASH, key), kit.Dict(
kit.MDB_NAME, value["name"], kit.MDB_GROUP, arg[0], kit.MDB_STATUS, "free",
kit.MDB_NAME, value["name"], kit.SSH_GROUP, arg[0], kit.MDB_STATUS, "free",
))
})
}

View File

@ -21,19 +21,19 @@ func _route_travel(m *ice.Message, route string) {
// 远程查询
m.Cmd(SPACE, val[kit.MDB_NAME], ROUTE).Table(func(index int, value map[string]string, head []string) {
m.Push(kit.MDB_TYPE, value[kit.MDB_TYPE])
m.Push(kit.MDB_ROUTE, kit.Keys(val[kit.MDB_NAME], value[kit.MDB_ROUTE]))
m.Push(kit.SSH_ROUTE, kit.Keys(val[kit.MDB_NAME], value[kit.SSH_ROUTE]))
})
fallthrough
case WORKER:
// 本机查询
m.Push(kit.MDB_TYPE, val[kit.MDB_TYPE])
m.Push(kit.MDB_ROUTE, val[kit.MDB_NAME])
m.Push(kit.SSH_ROUTE, val[kit.MDB_NAME])
}
})
} else {
m.Cmd(SPACE, route, ROUTE).Table(func(index int, value map[string]string, head []string) {
m.Push(kit.MDB_TYPE, value[kit.MDB_TYPE])
m.Push(kit.MDB_ROUTE, kit.Keys(route, value[kit.MDB_ROUTE]))
m.Push(kit.SSH_ROUTE, kit.Keys(route, value[kit.SSH_ROUTE]))
})
}
}
@ -43,7 +43,7 @@ const ROUTE = "route"
func init() {
Index.Merge(&ice.Context{
Configs: map[string]*ice.Config{
ROUTE: {Name: ROUTE, Help: "路由器", Value: kit.Data(kit.MDB_SHORT, kit.MDB_ROUTE)},
ROUTE: {Name: ROUTE, Help: "路由器", Value: kit.Data(kit.MDB_SHORT, kit.SSH_ROUTE)},
},
Commands: map[string]*ice.Command{
ROUTE: {Name: "route route ctx cmd auto 添加", Help: "路由", Action: map[string]*ice.Action{
@ -112,8 +112,8 @@ func init() {
m.Push("route", MYSELF)
m.Table(func(index int, value map[string]string, field []string) {
m.PushRender(kit.MDB_LINK, "a", value[kit.MDB_ROUTE],
kit.MergeURL(m.Option(ice.MSG_USERWEB), "pod", kit.Keys(m.Option("pod", value[kit.MDB_ROUTE]))))
m.PushRender(kit.MDB_LINK, "a", value[kit.SSH_ROUTE],
kit.MergeURL(m.Option(ice.MSG_USERWEB), "pod", kit.Keys(m.Option("pod", value[kit.SSH_ROUTE]))))
switch value[kit.MDB_TYPE] {
case MYSELF, SERVER:
m.PushRender("action", "button", "启动")
@ -121,7 +121,7 @@ func init() {
m.PushRender("action", "button", "结束")
}
})
m.Sort(kit.MDB_ROUTE)
m.Sort(kit.SSH_ROUTE)
}},
"/route/": {Name: "/route/", Help: "路由器", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
switch arg[0] {

View File

@ -27,7 +27,7 @@ func _serve_login(msg *ice.Message, cmds []string, w http.ResponseWriter, r *htt
aaa.SessCheck(msg, msg.Option(ice.MSG_SESSID))
}
if !msg.Options(ice.MSG_USERNAME) && tcp.IPIsLocal(msg, msg.Option(ice.MSG_USERIP)) {
if !msg.Options(ice.MSG_USERNAME) && tcp.IsLocalHost(msg, msg.Option(ice.MSG_USERIP)) {
// 自动认证
if aaa.UserLogin(msg, cli.UserName, cli.PassWord) {
if strings.HasPrefix(msg.Option(ice.MSG_USERUA), "Mozilla/5.0") {

View File

@ -4,11 +4,9 @@ import (
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/aaa"
"github.com/shylinux/icebergs/base/cli"
"github.com/shylinux/icebergs/base/ctx"
"github.com/shylinux/icebergs/base/mdb"
kit "github.com/shylinux/toolkits"
"fmt"
"net/http"
"os"
"path"
@ -16,51 +14,6 @@ import (
"time"
)
func _share_list(m *ice.Message, key string, fields ...string) {
if key == "" {
m.Grows(SHARE, nil, "", "", func(index int, value map[string]interface{}) {
m.Push("", value, []string{kit.MDB_TIME, kit.MDB_SHARE, kit.MDB_TYPE, kit.MDB_NAME, kit.MDB_TEXT})
m.Push(kit.MDB_LINK, fmt.Sprintf(m.Conf(SHARE, "meta.template.link"), m.Conf(SHARE, "meta.domain"), value[kit.MDB_SHARE], value[kit.MDB_SHARE]))
})
return
}
m.Richs(SHARE, nil, key, func(key string, value map[string]interface{}) {
m.Push("detail", value)
m.Push(kit.MDB_KEY, kit.MDB_LINK)
m.Push(kit.MDB_VALUE, m.Cmdx(mdb.RENDER, RENDER.A, key, URL(m, kit.Format("/share/%s", key))))
m.Push(kit.MDB_KEY, kit.MDB_SHARE)
m.Push(kit.MDB_VALUE, m.Cmdx(mdb.RENDER, RENDER.IMG, URL(m, kit.Format("/share/%s/share", key))))
m.Push(kit.MDB_KEY, kit.MDB_VALUE)
m.Push(kit.MDB_VALUE, m.Cmdx(mdb.RENDER, RENDER.IMG, URL(m, kit.Format("/share/%s/value", key))))
})
}
func _share_show(m *ice.Message, key string, value map[string]interface{}, arg ...string) bool {
switch kit.Select("", arg, 0) {
case "check", "安全码":
m.Render(ice.RENDER_QRCODE, kit.Format(kit.Dict(
kit.MDB_TYPE, SHARE, kit.MDB_NAME, value[kit.MDB_TYPE], kit.MDB_TEXT, key,
)))
case kit.MDB_SHARE, "共享码":
m.Render(ice.RENDER_QRCODE, kit.Format("%s/share/%s/?share=%s", m.Conf(SHARE, "meta.domain"), key, key))
case kit.MDB_VALUE, "数据值":
m.Render(ice.RENDER_QRCODE, kit.Format(value), kit.Select("256", arg, 1))
case kit.MDB_TEXT:
m.Render(ice.RENDER_QRCODE, kit.Format(value[kit.MDB_TEXT]))
case "detail", "详情":
m.Render(kit.Formats(value))
case "download", "下载":
if strings.HasPrefix(kit.Format(value["text"]), m.Conf(CACHE, "meta.path")) {
m.Render(ice.RENDER_DOWNLOAD, value["text"], value["type"], value["name"])
} else {
m.Render("%s", value["text"])
}
default:
return false
}
return true
}
func _share_repos(m *ice.Message, repos string, arg ...string) {
prefix := m.Conf(SERVE, "meta.volcanos.require")
if _, e := os.Stat(path.Join(prefix, repos)); e != nil {
@ -68,6 +21,10 @@ func _share_repos(m *ice.Message, repos string, arg ...string) {
}
m.Render(ice.RENDER_DOWNLOAD, path.Join(prefix, repos, path.Join(arg...)))
}
func _share_remote(m *ice.Message, pod string, arg ...string) {
m.Cmdy(SPACE, pod, "web./publish/", arg)
m.Render(ice.RENDER_RESULT)
}
func _share_local(m *ice.Message, arg ...string) {
p := path.Join(arg...)
switch ls := strings.Split(p, "/"); ls[0] {
@ -114,148 +71,6 @@ func _share_cache(m *ice.Message, arg ...string) {
msg := m.Cmd(CACHE, arg[0])
m.Render(ice.RENDER_DOWNLOAD, msg.Append(kit.MDB_FILE), msg.Append(kit.MDB_TYPE), msg.Append(kit.MDB_NAME))
}
func _share_remote(m *ice.Message, pod string, arg ...string) {
m.Cmdy(SPACE, pod, "web./publish/", arg)
m.Render(ice.RENDER_RESULT)
}
func _share_create(m *ice.Message, kind, name, text string, arg ...string) string {
h := m.Rich(SHARE, nil, kit.Dict(
kit.MDB_TIME, m.Time(m.Conf(SHARE, "meta.expire")),
kit.MDB_TYPE, kind, kit.MDB_NAME, name, kit.MDB_TEXT, text,
kit.MDB_EXTRA, kit.Dict(
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),
))
// 创建列表
m.Grow(SHARE, nil, kit.Dict(
kit.MDB_TYPE, kind, kit.MDB_NAME, name, kit.MDB_TEXT, text,
kit.MDB_SHARE, h,
))
m.Log_CREATE(kit.MDB_SHARE, h, kit.MDB_TYPE, kind, kit.MDB_NAME, name)
m.Echo(h)
return h
}
func _share_story(m *ice.Message, value map[string]interface{}, arg ...string) map[string]interface{} {
msg := m.Cmd(STORY, INDEX, value["text"])
if msg.Append("text") == "" && kit.Value(value, "extra.pod") != "" {
msg = m.Cmd(SPACE, kit.Value(value, "extra.pod"), STORY, INDEX, value["text"])
}
value = kit.Dict("type", msg.Append("scene"), "name", msg.Append("story"), "text", msg.Append("text"), "file", msg.Append("file"))
m.Log(ice.LOG_EXPORT, "%s: %v", arg, kit.Format(value))
return value
}
func _share_action(m *ice.Message, value map[string]interface{}, arg ...string) bool {
if len(arg) == 1 || arg[1] == "" {
return _share_action_redirect(m, value, arg[0])
}
if arg[1] == "" {
return _share_action_page(m, value)
}
if len(arg) == 2 {
return _share_action_list(m, value, arg[0], arg[1])
}
// 默认参数
meta := kit.Value(value, kit.Format("extra.tool.%s", arg[2])).(map[string]interface{})
if meta["single"] == "yes" && kit.Select("", arg, 3) != "action" {
arg = append(arg[:3], kit.Simple(kit.UnMarshal(kit.Format(meta["args"])))...)
for i := len(arg) - 1; i >= 0; i-- {
if arg[i] != "" {
return true
}
arg = arg[:i]
}
}
// 执行命令
cmds := kit.Simple(m.Space(meta["pod"]), kit.Keys(meta["ctx"], meta["cmd"]), arg[3:])
m.Cmdy(cmds).Option("cmds", cmds)
m.Option("title", value["name"])
if strings.HasPrefix(kit.Format(value["text"]), m.Conf(CACHE, "meta.path")) {
m.Render(ice.RENDER_DOWNLOAD, value["text"], value["type"], value["name"])
} else {
m.Render("%s", value["text"])
}
return true
}
func _share_action_redirect(m *ice.Message, value map[string]interface{}, share string) bool {
tool := kit.Value(value, "extra.tool.0").(map[string]interface{})
m.Render("redirect", "/share", "share", share, "title", kit.Format(value["name"]),
"river", kit.Format(kit.Value(value, "extra.river")),
"storm", kit.Format(kit.Value(value, "extra.storm")),
"pod", kit.Format(tool["pod"]), kit.UnMarshal(kit.Format(tool["val"])),
)
return true
}
func _share_action_page(m *ice.Message, value map[string]interface{}) bool {
Render(m, ice.RENDER_DOWNLOAD, m.Conf(SERVE, "meta.page.share"))
return true
}
func _share_action_list(m *ice.Message, value map[string]interface{}, river, storm string) bool {
value["count"] = kit.Int(value["count"]) + 1
kit.Fetch(kit.Value(value, "extra.tool"), func(index int, value map[string]interface{}) {
m.Push("river", river)
m.Push("storm", storm)
m.Push("action", index)
m.Push("node", value["pod"])
m.Push("group", value["ctx"])
m.Push("index", value["cmd"])
m.Push("args", value["args"])
m.Push("value", value["value"])
msg := m.Cmd(m.Space(value["pod"]), ctx.COMMAND, value["ctx"], value["cmd"])
ls := strings.Split(kit.Format(value["cmd"]), ".")
m.Push("name", ls[len(ls)-1])
m.Push("help", kit.Select(msg.Append("help"), kit.Format(value["help"])))
m.Push("inputs", msg.Append("list"))
m.Push("feature", msg.Append("meta"))
})
return true
}
func _share_auth(m *ice.Message, share string, role string) {
m.Richs(SHARE, nil, share, func(key string, value map[string]interface{}) {
switch value["type"] {
case "active":
m.Cmdy(SPACE, value["name"], "sessid", m.Cmdx(aaa.SESS, "create", role))
case "user":
m.Cmdy(aaa.ROLE, role, value["name"])
default:
m.Cmdy(aaa.SESS, "auth", value["text"], role)
}
})
}
func _share_check(m *ice.Message, share string) {
m.Richs(SHARE, nil, share, func(key string, value map[string]interface{}) {
m.Render(ice.RENDER_QRCODE, kit.Format(kit.Dict(
kit.MDB_TYPE, "share", kit.MDB_NAME, value["type"], kit.MDB_TEXT, key,
)))
})
}
func _trash(m *ice.Message, arg ...string) {
switch arg[0] {
case "invite":
arg = []string{arg[0], m.Cmdx(SHARE, "invite", kit.Select("tech", arg, 1), kit.Select("miss", arg, 2))}
fallthrough
case "check":
_share_check(m, arg[1])
case "auth":
_share_auth(m, arg[1], arg[2])
case "add":
_share_create(m, arg[1], arg[2], arg[3], arg[4:]...)
default:
if len(arg) == 1 {
_share_list(m, arg[0])
break
}
}
}
const SHARE = "share"
@ -292,46 +107,6 @@ func init() {
"/share/cache/": {Name: "/share/cache/", Help: "缓存池", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
_share_cache(m, arg...)
}},
"/share/": {Name: "/share/", Help: "共享链", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Richs(SHARE, nil, kit.Select(m.Option(kit.MDB_SHARE), arg, 0), func(key string, value map[string]interface{}) {
m.Log_SELECT(kit.MDB_META, SHARE, "arg", arg, "value", kit.Format(value))
if m.Warn(m.Option(ice.MSG_USERROLE) != aaa.ROOT && kit.Time(kit.Format(value[kit.MDB_TIME])) < kit.Time(m.Time()), "expired") {
m.Echo("expired")
return
}
switch value[kit.MDB_TYPE] {
case STORY:
value = _share_story(m, value, arg...)
}
if _share_show(m, key, value, kit.Select("", arg, 1), kit.Select("", arg, 2)) {
return
}
switch value[kit.MDB_TYPE] {
case TYPE_RIVER:
// 共享群组
m.Render("redirect", "/", "share", key, "river", kit.Format(value["text"]))
case TYPE_STORM:
// 共享应用
m.Render("redirect", "/", "share", key, "storm", kit.Format(value["text"]), "river", kit.Format(kit.Value(value, "extra.river")))
case TYPE_ACTION:
_share_action(m, value, arg...)
default:
// 查看数据
m.Option(kit.MDB_VALUE, value)
m.Option(kit.MDB_TYPE, value[kit.MDB_TYPE])
m.Option(kit.MDB_NAME, value[kit.MDB_NAME])
m.Option(kit.MDB_TEXT, value[kit.MDB_TEXT])
m.Render(ice.RENDER_TEMPLATE, m.Conf(SHARE, "meta.template.simple"))
m.Option(ice.MSG_OUTPUT, ice.RENDER_RESULT)
}
})
}},
"/plugin/github.com/": {Name: "/space/", Help: "空间站", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
_share_repos(m, path.Join(strings.Split(cmd, "/")[2:5]...), arg[6:]...)
}},

View File

@ -2,6 +2,7 @@ package web
import (
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/aaa"
"github.com/shylinux/icebergs/base/cli"
"github.com/shylinux/icebergs/base/mdb"
"github.com/shylinux/icebergs/base/tcp"
@ -61,7 +62,7 @@ func _spide_login(m *ice.Message, name string) {
func _spide_create(m *ice.Message, name, address string, arg ...string) {
if uri, e := url.Parse(address); e == nil && address != "" {
if uri.Host == "random" {
uri.Host = ":" + m.Cmdx(tcp.PORT, "get")
uri.Host = ":" + m.Cmdx(tcp.PORT, aaa.Right)
address = strings.Replace(address, "random", uri.Host, -1)
}

View File

@ -7,10 +7,13 @@ import (
"github.com/shylinux/icebergs/base/ctx"
"github.com/shylinux/icebergs/base/gdb"
"github.com/shylinux/icebergs/base/mdb"
"github.com/shylinux/icebergs/base/tcp"
kit "github.com/shylinux/toolkits"
"net"
"net/http"
"path"
"strings"
)
type Frame struct {
@ -70,19 +73,18 @@ func (web *Frame) Start(m *ice.Message, arg ...string) bool {
}
})
// TODO simple
m.Richs(SPIDE, nil, arg[0], func(key string, value map[string]interface{}) {
client := value["client"].(map[string]interface{})
// 服务地址
port := m.Cap(ice.CTX_STREAM, client["hostname"])
m.Log("serve", "listen %s %s %v", arg[0], port, m.Conf(cli.RUNTIME, "node"))
web.m, web.Server = m, &http.Server{Handler: web}
m.Option(tcp.LISTEN_CB, func(l net.Listener) {
m.Event(gdb.SERVE_START, arg[0])
m.Warn(true, "listen %s", web.Server.Serve(l))
m.Event(gdb.SERVE_CLOSE, arg[0])
})
// 启动服务
web.m, web.Server = m, &http.Server{Addr: port, Handler: web}
m.Event(gdb.SERVE_START, arg[0])
m.Warn(true, "listen %s", web.Server.ListenAndServe())
m.Event(gdb.SERVE_CLOSE, arg[0])
ls := strings.Split(m.Cap(ice.CTX_STREAM, client["hostname"]), ":")
m.Cmd(tcp.SERVER, tcp.LISTEN, kit.MDB_NAME, "web", tcp.HOST, ls[0], tcp.PORT, ls[1])
})
return true
}
@ -104,7 +106,6 @@ var Index = &ice.Context{Name: "web", Help: "网络模块",
m.Cmd(aaa.ROLE, aaa.White, aaa.VOID, "web", "/publish/")
m.Cmd(aaa.ROLE, aaa.White, aaa.VOID, ctx.COMMAND)
m.Cmd(mdb.SEARCH, mdb.CREATE, FAVOR)
m.Cmd(mdb.SEARCH, mdb.CREATE, SPIDE)
m.Cmd(mdb.RENDER, mdb.CREATE, SPIDE)
m.Cmd(mdb.SEARCH, mdb.CREATE, SPACE)
@ -116,8 +117,7 @@ var Index = &ice.Context{Name: "web", Help: "网络模块",
})
}},
ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Save(SPIDE, SERVE, GROUP, LABEL,
FAVOR, CACHE, STORY, SHARE)
m.Save(SPIDE, SERVE, CACHE, SHARE, STORY)
m.Done()
m.Richs(SPACE, nil, "*", func(key string, value map[string]interface{}) {
@ -131,7 +131,6 @@ var Index = &ice.Context{Name: "web", Help: "网络模块",
func init() {
ice.Index.Register(Index, &Frame{},
SPIDE, SERVE, SPACE, DREAM,
CACHE, FAVOR, STORY, SHARE,
SPIDE, SERVE, SPACE, DREAM, CACHE, SHARE, STORY,
)
}

View File

@ -100,8 +100,8 @@ const ( // RENDER
RENDER_OUTPUT = "_output"
RENDER_RESULT = "_result"
RENDER_QRCODE = "_qrcode"
RENDER_TEMPLATE = "_template"
RENDER_DOWNLOAD = "_download"
RENDER_TEMPLATE = "_template"
)
const ( // TODO

View File

@ -36,7 +36,7 @@ func _action_show(m *ice.Message, river, storm, index string, arg ...string) {
prefix := kit.Keys(kit.MDB_HASH, river, TOOL, kit.MDB_HASH, storm)
if m.Grows(RIVER, prefix, kit.MDB_ID, index, func(index int, value map[string]interface{}) {
if cmds = kit.Simple(kit.Keys(value[CTX], value[CMD])); kit.Format(value[POD]) != "" {
m.Option(kit.GDB_POD, value[POD])
m.Option(kit.SSH_POD, value[POD])
}
}) == nil && m.Warn(!m.Right(cmds), ice.ErrNotAuth) {
return

View File

@ -124,7 +124,7 @@ func init() {
m.Cmdy(mdb.SELECT, RIVER, kit.Keys(kit.MDB_HASH, m.Option(ice.MSG_RIVER), NODE), mdb.HASH)
m.Table(func(index int, value map[string]string, head []string) {
m.PushRender(kit.MDB_LINK, "a", value[kit.MDB_NAME],
kit.MergeURL(m.Option(ice.MSG_USERWEB), kit.GDB_POD, kit.Keys(m.Option(kit.GDB_POD), value[kit.MDB_NAME])))
kit.MergeURL(m.Option(ice.MSG_USERWEB), kit.SSH_POD, kit.Keys(m.Option(kit.SSH_POD), value[kit.MDB_NAME])))
})
m.PushAction("删除")
return

59
core/code/_trash.go Normal file
View File

@ -0,0 +1,59 @@
package code
func _pprof_show(m *ice.Message, zone string, id string) {
favor := m.Conf(PPROF, kit.Keys(kit.MDB_META, web.FAVOR))
m.Richs(PPROF, nil, zone, func(key string, val map[string]interface{}) {
val = val[kit.MDB_META].(map[string]interface{})
list := []string{}
task.Put(val, func(task *task.Task) error {
m.Sleep("1s")
m.Grows(PPROF, kit.Keys(kit.MDB_HASH, key), "", "", func(index int, value map[string]interface{}) {
// 压测命令
m.Log_EXPORT(kit.MDB_META, PPROF, kit.MDB_ZONE, zone, kit.MDB_VALUE, kit.Format(value))
cmd := kit.Format(value[kit.MDB_TYPE])
arg := kit.Format(value[kit.MDB_TEXT])
res := m.Cmd(mdb.ENGINE, value[kit.MDB_TYPE], value[kit.MDB_NAME], value[kit.MDB_TEXT], value[kit.MDB_EXTRA]).Result()
m.Cmd(web.FAVOR, favor, cmd, arg, res)
list = append(list, cmd+": "+arg, res)
})
return nil
})
// 收藏程序
msg := m.Cmd(web.CACHE, web.CATCH, kit.MIME_FILE, kit.Format(val[BINNARY]))
bin := msg.Append(kit.MDB_TEXT)
m.Cmd(web.FAVOR, favor, kit.MIME_FILE, bin, val[BINNARY])
// 性能分析
msg = m.Cmd(web.SPIDE, "self", web.CACHE, http.MethodGet, kit.Select("/code/pprof/profile", val[SERVICE]), "seconds", kit.Select("5", kit.Format(val[SECONDS])))
m.Cmd(web.FAVOR, favor, PPROF, msg.Append(kit.MDB_TEXT), kit.Keys(zone, "pd.gz"))
// 结果摘要
cmd := kit.Simple(m.Confv(PPROF, "meta.pprof"), "-text", val[BINNARY], msg.Append(kit.MDB_TEXT))
res := strings.Split(m.Cmdx(cli.SYSTEM, cmd), "\n")
if len(res) > 20 {
res = res[:20]
}
m.Cmd(web.FAVOR, favor, web.TYPE_SHELL, strings.Join(cmd, " "), strings.Join(res, "\n"))
list = append(list, web.TYPE_SHELL+": "+strings.Join(cmd, " "), strings.Join(res, "\n"))
// 结果展示
u := kit.ParseURL(m.Option(ice.MSG_USERWEB))
p := kit.Format("%s:%s", u.Hostname(), m.Cmdx(tcp.PORT, aaa.Right))
m.Option(cli.CMD_STDOUT, "var/daemon/stdout")
m.Option(cli.CMD_STDERR, "var/daemon/stderr")
m.Cmd(cli.DAEMON, m.Confv(PPROF, "meta.pprof"), "-http="+p, val[BINNARY], msg.Append(kit.MDB_TEXT))
url := u.Scheme + "://" + p + "/ui/top"
m.Cmd(web.FAVOR, favor, web.SPIDE, url, msg.Append(kit.MDB_TEXT))
m.Set(ice.MSG_RESULT).Echo(url).Echo(" \n").Echo("\n")
m.Echo(strings.Join(list, "\n")).Echo("\n")
m.Push("url", url)
m.Push(PPROF, msg.Append(kit.MDB_TEXT))
m.Push(SERVICE, strings.Replace(kit.Format(val[SERVICE]), "profile", "", -1))
m.Push("bin", bin)
})
}

View File

@ -2,6 +2,7 @@ package code
import (
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/aaa"
"github.com/shylinux/icebergs/base/cli"
"github.com/shylinux/icebergs/base/mdb"
"github.com/shylinux/icebergs/base/nfs"
@ -49,10 +50,10 @@ func init() {
value = value[kit.MDB_META].(map[string]interface{})
m.Optionv("progress", func(size int, total int) {
s := size * 100 / total
if s != kit.Int(value[kit.MDB_STEP]) && s%10 == 0 {
m.Log_IMPORT(kit.MDB_FILE, name, kit.MDB_STEP, s, kit.MDB_SIZE, kit.FmtSize(int64(size)), kit.MDB_TOTAL, kit.FmtSize(int64(total)))
if s != kit.Int(value[kit.SSH_STEP]) && s%10 == 0 {
m.Log_IMPORT(kit.MDB_FILE, name, kit.SSH_STEP, s, kit.MDB_SIZE, kit.FmtSize(int64(size)), kit.MDB_TOTAL, kit.FmtSize(int64(total)))
}
value[kit.MDB_STEP], value[kit.MDB_SIZE], value[kit.MDB_TOTAL] = s, size, total
value[kit.SSH_STEP], value[kit.MDB_SIZE], value[kit.MDB_TOTAL] = s, size, total
})
})
@ -85,7 +86,7 @@ func init() {
m.Cmdy(cli.SYSTEM, "make", "PREFIX="+kit.Path(path.Join(p, kit.Select("_install", m.Option("install")))), "install")
}},
"spawn": {Name: "spawn link", Help: "新建", Hand: func(m *ice.Message, arg ...string) {
port := m.Cmdx(tcp.PORT, "select")
port := m.Cmdx(tcp.PORT, aaa.Right)
target := path.Join(m.Conf(cli.DAEMON, kit.META_PATH), port)
source := path.Join(m.Conf(INSTALL, kit.META_PATH), kit.TrimExt(arg[0]))
@ -122,10 +123,10 @@ func init() {
// 服务列表
if strings.Contains(value[kit.MDB_NAME], key) {
m.Push(kit.MDB_TIME, value[kit.MDB_TIME])
m.Push(kit.MDB_PORT, path.Base(value[kit.MDB_DIR]))
m.Push(kit.SSH_PORT, path.Base(value[kit.SSH_DIR]))
m.Push(kit.MDB_STATUS, value[kit.MDB_STATUS])
m.Push(kit.MDB_NAME, value[kit.MDB_NAME])
m.PushRender(kit.MDB_LINK, "a", kit.Format("http://%s:%s", u.Hostname(), path.Base(value[kit.MDB_DIR])))
m.PushRender(kit.MDB_LINK, "a", kit.Format("http://%s:%s", u.Hostname(), path.Base(value[kit.SSH_DIR])))
}
})
return

View File

@ -2,12 +2,9 @@ package code
import (
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/cli"
"github.com/shylinux/icebergs/base/mdb"
"github.com/shylinux/icebergs/base/tcp"
"github.com/shylinux/icebergs/base/web"
kit "github.com/shylinux/toolkits"
"github.com/shylinux/toolkits/task"
"net/http"
_ "net/http/pprof"
@ -36,63 +33,6 @@ func _pprof_list(m *ice.Message, zone string, id string, field ...interface{}) {
}
})
}
func _pprof_show(m *ice.Message, zone string, id string) {
favor := m.Conf(PPROF, kit.Keys(kit.MDB_META, web.FAVOR))
m.Richs(PPROF, nil, zone, func(key string, val map[string]interface{}) {
val = val[kit.MDB_META].(map[string]interface{})
list := []string{}
task.Put(val, func(task *task.Task) error {
m.Sleep("1s")
m.Grows(PPROF, kit.Keys(kit.MDB_HASH, key), "", "", func(index int, value map[string]interface{}) {
// 压测命令
m.Log_EXPORT(kit.MDB_META, PPROF, kit.MDB_ZONE, zone, kit.MDB_VALUE, kit.Format(value))
cmd := kit.Format(value[kit.MDB_TYPE])
arg := kit.Format(value[kit.MDB_TEXT])
res := m.Cmd(mdb.ENGINE, value[kit.MDB_TYPE], value[kit.MDB_NAME], value[kit.MDB_TEXT], value[kit.MDB_EXTRA]).Result()
m.Cmd(web.FAVOR, favor, cmd, arg, res)
list = append(list, cmd+": "+arg, res)
})
return nil
})
// 收藏程序
msg := m.Cmd(web.CACHE, web.CATCH, kit.MIME_FILE, kit.Format(val[BINNARY]))
bin := msg.Append(kit.MDB_TEXT)
m.Cmd(web.FAVOR, favor, kit.MIME_FILE, bin, val[BINNARY])
// 性能分析
msg = m.Cmd(web.SPIDE, "self", web.CACHE, http.MethodGet, kit.Select("/code/pprof/profile", val[SERVICE]), "seconds", kit.Select("5", kit.Format(val[SECONDS])))
m.Cmd(web.FAVOR, favor, PPROF, msg.Append(kit.MDB_TEXT), kit.Keys(zone, "pd.gz"))
// 结果摘要
cmd := kit.Simple(m.Confv(PPROF, "meta.pprof"), "-text", val[BINNARY], msg.Append(kit.MDB_TEXT))
res := strings.Split(m.Cmdx(cli.SYSTEM, cmd), "\n")
if len(res) > 20 {
res = res[:20]
}
m.Cmd(web.FAVOR, favor, web.TYPE_SHELL, strings.Join(cmd, " "), strings.Join(res, "\n"))
list = append(list, web.TYPE_SHELL+": "+strings.Join(cmd, " "), strings.Join(res, "\n"))
// 结果展示
u := kit.ParseURL(m.Option(ice.MSG_USERWEB))
p := kit.Format("%s:%s", u.Hostname(), m.Cmdx(tcp.PORT, "get"))
m.Option(cli.CMD_STDOUT, "var/daemon/stdout")
m.Option(cli.CMD_STDERR, "var/daemon/stderr")
m.Cmd(cli.DAEMON, m.Confv(PPROF, "meta.pprof"), "-http="+p, val[BINNARY], msg.Append(kit.MDB_TEXT))
url := u.Scheme + "://" + p + "/ui/top"
m.Cmd(web.FAVOR, favor, web.SPIDE, url, msg.Append(kit.MDB_TEXT))
m.Set(ice.MSG_RESULT).Echo(url).Echo(" \n").Echo("\n")
m.Echo(strings.Join(list, "\n")).Echo("\n")
m.Push("url", url)
m.Push(PPROF, msg.Append(kit.MDB_TEXT))
m.Push(SERVICE, strings.Replace(kit.Format(val[SERVICE]), "profile", "", -1))
m.Push("bin", bin)
})
}
func _pprof_modify(m *ice.Message, zone, id, k, v, old string) {
k = kit.Select(k, m.Option(kit.MDB_KEY))
m.Richs(PPROF, nil, kit.Select(kit.MDB_FOREACH, zone), func(key string, val map[string]interface{}) {
@ -141,7 +81,7 @@ func init() {
Index.Merge(&ice.Context{
Configs: map[string]*ice.Config{
PPROF: {Name: "pprof", Help: "性能分析", Value: kit.Data(kit.MDB_SHORT, kit.MDB_ZONE,
web.FAVOR, "pprof", PPROF, []string{"go", "tool", "pprof"},
PPROF, []string{"go", "tool", "pprof"},
)},
},
Commands: map[string]*ice.Command{
@ -163,7 +103,7 @@ func init() {
_pprof_modify(m, m.Option(kit.MDB_ZONE), m.Option(kit.MDB_ID), arg[0], arg[1], kit.Select("", arg, 2))
}},
kit.MDB_SHOW: {Name: "show type name text arg...", Help: "运行", Hand: func(m *ice.Message, arg ...string) {
_pprof_show(m, m.Option(kit.MDB_ZONE), m.Option(kit.MDB_ID))
// _pprof_show(m, m.Option(kit.MDB_ZONE), m.Option(kit.MDB_ID))
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
_pprof_list(m, kit.Select(kit.MDB_FOREACH, arg, 0), kit.Select("", arg, 1))

View File

@ -7,7 +7,6 @@ import (
"github.com/shylinux/icebergs/base/mdb"
kit "github.com/shylinux/toolkits"
"path"
"time"
)
@ -20,7 +19,6 @@ func init() {
"display", "/plugin/local/team/plan.js", "style", "plan",
), Action: map[string]*ice.Action{
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_insert(m, arg[1], arg[2:]...)
}},
mdb.MODIFY: {Name: "modify", Help: "编辑", Hand: func(m *ice.Message, arg ...string) {
@ -30,20 +28,20 @@ func init() {
_task_delete(m, m.Option(kit.MDB_ZONE), m.Option(kit.MDB_ID))
}},
mdb.EXPORT: {Name: "export file", Help: "导出", Hand: func(m *ice.Message, arg ...string) {
_task_export(m, kit.Select(path.Join(EXPORT, m.Option(ice.MSG_DOMAIN), "list.csv")))
_task_export(m, m.Option(kit.MDB_FILE))
}},
mdb.IMPORT: {Name: "import file", Help: "导入", Hand: func(m *ice.Message, arg ...string) {
_task_import(m, kit.Select(path.Join(EXPORT, m.Option(ice.MSG_DOMAIN), "list.csv")))
_task_import(m, m.Option(kit.MDB_FILE))
}},
mdb.INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) {
_task_input(m, kit.Select("", arg, 0), kit.Select("", arg, 1))
_task_inputs(m, kit.Select("", arg, 0), kit.Select("", arg, 1))
}},
gdb.BEGIN: {Name: "begin", Help: "开始", Hand: func(m *ice.Message, arg ...string) {
_task_modify(m, m.Option(kit.MDB_ZONE), m.Option(kit.MDB_ID), STATUS, StatusProcess)
_task_modify(m, m.Option(kit.MDB_ZONE), m.Option(kit.MDB_ID), TaskField.STATUS, TaskStatus.PROCESS)
}},
gdb.END: {Name: "end", Help: "完成", Hand: func(m *ice.Message, arg ...string) {
_task_modify(m, m.Option(kit.MDB_ZONE), m.Option(kit.MDB_ID), STATUS, StatusFinish)
_task_modify(m, m.Option(kit.MDB_ZONE), m.Option(kit.MDB_ID), TaskField.STATUS, TaskStatus.FINISH)
}},
"command": {Name: "command", Help: "命令", Hand: func(m *ice.Message, arg ...string) {
@ -54,21 +52,20 @@ func init() {
m.Cmdy(arg[0], arg[1:])
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
begin_time, end_time := _task_scope(m, arg...)
m.Set(ice.MSG_OPTION, "end_time")
begin_time, end_time := _task_scope(m, 8, arg...)
m.Set(ice.MSG_OPTION, "begin_time")
m.Richs(TASK, kit.Keys(kit.MDB_HASH, m.Optionv(ice.MSG_DOMAIN)), kit.Select(kit.MDB_FOREACH, m.Option(kit.MDB_ZONE)), func(key string, val map[string]interface{}) {
zone := kit.Format(kit.Value(val, "meta.zone"))
m.Grows(TASK, kit.Keys(kit.MDB_HASH, m.Optionv(ice.MSG_DOMAIN), kit.MDB_HASH, key), "", "", func(index int, value map[string]interface{}) {
begin, _ := time.ParseInLocation(ice.MOD_TIME, kit.Format(value[BEGIN_TIME]), time.Local)
if begin_time.Before(begin) && begin.Before(end_time) {
m.Push(zone, value)
m.Push(kit.MDB_ZONE, zone)
m.PushAction(_task_action(m, value[STATUS], "插件"))
}
})
m.Set(ice.MSG_OPTION, "end_time")
m.Option(mdb.FIELDS, "begin_time,close_time,zone,id,level,status,score,type,name,text,extra")
m.Option("cache.cb", func(key string, fields []string, value, val map[string]interface{}) {
begin, _ := time.ParseInLocation(ice.MOD_TIME, kit.Format(value[TaskField.BEGIN_TIME]), time.Local)
if begin_time.After(begin) || begin.After(end_time) {
return
}
m.Push(key, value, fields, val)
m.PushRender(kit.MDB_ACTION, kit.MDB_BUTTON, _task_action(m, value[TaskField.STATUS], "插件"))
})
m.Cmdy(mdb.SELECT, m.Prefix(TASK), kit.Keys(m.Option(ice.MSG_DOMAIN)), mdb.ZONE)
}},
},
}, nil)

View File

@ -6,60 +6,84 @@ import (
"github.com/shylinux/icebergs/base/mdb"
kit "github.com/shylinux/toolkits"
"path"
"strings"
"time"
)
func _sub_key(m *ice.Message, zone string) string {
return kit.Keys(m.Optionv(ice.MSG_DOMAIN), kit.MDB_HASH, kit.Hashs(zone))
return kit.Keys(m.Option(ice.MSG_DOMAIN), kit.MDB_HASH, kit.Hashs(zone))
}
func _task_action(m *ice.Message, status interface{}, action ...string) string {
switch status {
case TaskStatus.PREPARE:
action = append(action, "开始")
case TaskStatus.PROCESS:
action = append(action, "完成")
case TaskStatus.CANCEL:
case TaskStatus.FINISH:
}
return strings.Join(action, ",")
}
func _task_list(m *ice.Message, zone string, id string) {
m.Option(mdb.FIELDS, "begin_time,zone,id,status,level,type,name,text")
m.Cmdy(mdb.SELECT, m.Prefix(TASK), kit.Keys(m.Optionv(ice.MSG_DOMAIN)), mdb.ZONE, zone, id)
if zone == "" {
m.Option(mdb.FIELDS, "time,zone,count")
} else if id == "" {
m.Option(mdb.FIELDS, "begin_time,id,status,level,score,type,name,text")
defer m.Table(func(index int, value map[string]string, head []string) {
m.PushRender(kit.MDB_ACTION, kit.MDB_BUTTON, _task_action(m, value[TaskField.STATUS]))
})
} else {
m.Option(mdb.FIELDS, mdb.DETAIL)
defer m.Table(func(index int, value map[string]string, head []string) {
if value[kit.MDB_KEY] == kit.MDB_STATUS {
m.Push(kit.MDB_KEY, kit.MDB_ACTION)
m.PushRender(kit.MDB_VALUE, kit.MDB_BUTTON, _task_action(m, value[kit.MDB_VALUE]))
}
})
}
m.Cmdy(mdb.SELECT, m.Prefix(TASK), m.Option(ice.MSG_DOMAIN), mdb.ZONE, zone, id)
}
func _task_create(m *ice.Message, zone string) {
m.Conf(m.Prefix(TASK), kit.Keys(m.Optionv(ice.MSG_DOMAIN), kit.MDB_META, kit.MDB_SHORT), kit.MDB_ZONE)
m.Cmdy(mdb.INSERT, m.Prefix(TASK), kit.Keys(m.Optionv(ice.MSG_DOMAIN)), mdb.HASH, kit.MDB_ZONE, zone)
if msg := m.Cmd(mdb.SELECT, m.Prefix(TASK), m.Option(ice.MSG_DOMAIN), mdb.HASH, kit.MDB_ZONE, zone); len(msg.Appendv(kit.MDB_HASH)) == 0 {
m.Conf(m.Prefix(TASK), kit.Keys(m.Option(ice.MSG_DOMAIN), kit.MDB_META, kit.MDB_SHORT), kit.MDB_ZONE)
m.Cmdy(mdb.INSERT, m.Prefix(TASK), m.Option(ice.MSG_DOMAIN), mdb.HASH, kit.MDB_ZONE, zone)
}
}
func _task_insert(m *ice.Message, zone string, arg ...string) {
if msg := m.Cmd(mdb.SELECT, m.Prefix(TASK), kit.Keys(m.Optionv(ice.MSG_DOMAIN)), mdb.HASH, kit.MDB_ZONE, zone); len(msg.Appendv(kit.MDB_HASH)) == 0 {
m.Debug("what %v", msg.Formats("meta"))
_task_create(m, zone)
}
m.Cmdy(mdb.INSERT, m.Prefix(TASK), _sub_key(m, zone), mdb.LIST,
BEGIN_TIME, m.Time(), CLOSE_TIME, m.Time("30m"), STATUS, StatusPrepare, LEVEL, 3, SCORE, 3, arg,
TaskField.BEGIN_TIME, m.Time(), TaskField.CLOSE_TIME, m.Time("30m"),
TaskField.STATUS, TaskStatus.PREPARE, TaskField.LEVEL, 3, TaskField.SCORE, 3,
arg,
)
}
func _task_modify(m *ice.Message, zone, id, field, value string, arg ...string) {
if field == STATUS {
if field == TaskField.STATUS {
switch value {
case StatusProcess:
arg = append(arg, BEGIN_TIME, m.Time())
case StatusCancel, StatusFinish:
arg = append(arg, CLOSE_TIME, m.Time())
case TaskStatus.PROCESS:
arg = append(arg, TaskField.BEGIN_TIME, m.Time())
case TaskStatus.CANCEL, TaskStatus.FINISH:
arg = append(arg, TaskField.CLOSE_TIME, m.Time())
}
}
m.Cmdy(mdb.MODIFY, m.Prefix(TASK), _sub_key(m, zone), mdb.LIST, kit.MDB_ID, id, field, value, arg)
}
func _task_delete(m *ice.Message, zone, id string) {
m.Cmdy(mdb.MODIFY, m.Prefix(TASK), _sub_key(m, zone), mdb.LIST, kit.MDB_ID, id, STATUS, StatusCancel)
m.Cmdy(mdb.MODIFY, m.Prefix(TASK), _sub_key(m, zone), mdb.LIST, kit.MDB_ID, id, TaskField.STATUS, TaskStatus.CANCEL)
}
func _task_export(m *ice.Message, file string) {
m.Option(mdb.FIELDS, "zone,id,time,type,name,text,level,status,score,begin_time,close_time,extra")
m.Cmdy(mdb.EXPORT, m.Prefix(TASK), kit.Keys(m.Optionv(ice.MSG_DOMAIN)), mdb.ZONE)
m.Cmdy(mdb.EXPORT, m.Prefix(TASK), m.Option(ice.MSG_DOMAIN), mdb.ZONE, file)
}
func _task_import(m *ice.Message, file string) {
m.Option(mdb.FIELDS, kit.MDB_ZONE)
m.Cmdy(mdb.IMPORT, m.Prefix(TASK), kit.Keys(m.Optionv(ice.MSG_DOMAIN)), mdb.ZONE, file)
m.Option(mdb.FIELDS, "zone")
m.Cmdy(mdb.IMPORT, m.Prefix(TASK), m.Option(ice.MSG_DOMAIN), mdb.ZONE, file)
}
func _task_input(m *ice.Message, field, value string) {
func _task_inputs(m *ice.Message, field, value string) {
switch field {
case kit.MDB_ZONE:
m.Cmdy(mdb.INPUTS, m.Prefix(TASK), kit.Keys(m.Optionv(ice.MSG_DOMAIN)), mdb.HASH, field, value)
case kit.MDB_NAME, kit.MDB_TEXT:
m.Cmdy(mdb.INPUTS, m.Prefix(TASK), m.Option(ice.MSG_DOMAIN), mdb.HASH, field, value)
case kit.MDB_TYPE, kit.MDB_NAME, kit.MDB_TEXT:
m.Cmdy(mdb.INPUTS, m.Prefix(TASK), _sub_key(m, m.Option(kit.MDB_ZONE)), mdb.LIST, field, value)
}
}
@ -89,95 +113,88 @@ func _task_render(m *ice.Message, kind, name, text string, arg ...string) {
})
})
}
func _task_action(m *ice.Message, status interface{}, action ...string) []string {
switch status {
case StatusPrepare:
action = append(action, "开始")
case StatusProcess:
action = append(action, "完成")
case StatusCancel, StatusFinish:
}
return action
}
func _task_scope(m *ice.Message, arg ...string) (time.Time, time.Time) {
func _task_scope(m *ice.Message, tz int, arg ...string) (time.Time, time.Time) {
begin_time := time.Now()
if len(arg) > 1 {
begin_time, _ = time.ParseInLocation(ice.MOD_TIME, arg[1], time.Local)
}
end_time := begin_time
switch begin_time = begin_time.Add(-time.Duration(begin_time.UnixNano()) % (24 * time.Hour)); arg[0] {
case ScaleDay:
end_time := begin_time
switch begin_time = begin_time.Add(-time.Duration(begin_time.UnixNano())%(24*time.Hour) - time.Duration(tz)*time.Hour); arg[0] {
case TaskScale.DAY:
end_time = begin_time.AddDate(0, 0, 1)
case ScaleWeek:
case TaskScale.WEEK:
begin_time = begin_time.AddDate(0, 0, -int(begin_time.Weekday()))
end_time = begin_time.AddDate(0, 0, 7)
case ScaleMonth:
case TaskScale.MONTH:
begin_time = begin_time.AddDate(0, 0, -begin_time.Day()+1)
end_time = begin_time.AddDate(0, 1, 0)
case ScaleYear:
case TaskScale.YEAR:
begin_time = begin_time.AddDate(0, 0, -begin_time.YearDay()+1)
end_time = begin_time.AddDate(1, 0, 0)
case ScaleLong:
case TaskScale.LONG:
begin_time = begin_time.AddDate(0, 0, -begin_time.YearDay()+1)
begin_time = begin_time.AddDate(-begin_time.Year()%5, 0, 0)
end_time = begin_time.AddDate(5, 0, 0)
}
begin_time = begin_time.Add(-8 * time.Hour)
end_time = end_time.Add(-8 * time.Hour)
return begin_time, end_time
}
const (
LEVEL = "level"
STATUS = "status"
SCORE = "score"
var TaskField = struct{ LEVEL, STATUS, SCORE, BEGIN_TIME, CLOSE_TIME string }{
LEVEL: "level",
STATUS: "status",
SCORE: "score",
BEGIN_TIME = "begin_time"
CLOSE_TIME = "close_time"
BEGIN_TIME: "begin_time",
CLOSE_TIME: "close_time",
}
var TaskStatus = struct{ PREPARE, PROCESS, CANCEL, FINISH string }{
PREPARE: "prepare",
PROCESS: "process",
CANCEL: "cancel",
FINISH: "finish",
}
var TaskType = struct{ ONCE, STEP, WEEK string }{
ONCE: "once",
STEP: "step",
WEEK: "week",
}
var TaskScale = struct{ DAY, WEEK, MONTH, YEAR, LONG string }{
DAY: "day",
WEEK: "week",
MONTH: "month",
YEAR: "year",
LONG: "long",
}
EXPORT = "usr/export/web.team.task/"
)
const (
ScaleDay = "day"
ScaleWeek = "week"
ScaleMonth = "month"
ScaleYear = "year"
ScaleLong = "long"
)
const (
StatusPrepare = "prepare"
StatusProcess = "process"
StatusCancel = "cancel"
StatusFinish = "finish"
)
const TASK = "task"
func init() {
Index.Merge(&ice.Context{
Configs: map[string]*ice.Config{
TASK: {Name: "task", Help: "task", Value: kit.Data(kit.MDB_SHORT, kit.MDB_ZONE)},
TASK: {Name: TASK, Help: "任务", Value: kit.Data(kit.MDB_SHORT, kit.MDB_ZONE)},
},
Commands: map[string]*ice.Command{
TASK: {Name: "task zone id auto 添加 导出 导入", Help: "任务", Action: map[string]*ice.Action{
mdb.INSERT: {Name: "insert zone@key type=once,step,week name@key text@key begin_time@date close_time@date", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
_task_create(m, arg[1])
_task_insert(m, arg[1], arg[2:]...)
}},
mdb.MODIFY: {Name: "modify key value", 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])
}},
mdb.DELETE: {Name: "delete", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
_task_delete(m, m.Option(kit.MDB_ZONE), m.Option(kit.MDB_ID))
}},
mdb.EXPORT: {Name: "export", Help: "导出", Hand: func(m *ice.Message, arg ...string) {
_task_export(m, kit.Select(path.Join(EXPORT, m.Option(ice.MSG_DOMAIN), "list.csv"), arg, 0))
mdb.EXPORT: {Name: "export file", Help: "导出", Hand: func(m *ice.Message, arg ...string) {
_task_export(m, m.Option(kit.MDB_FILE))
}},
mdb.IMPORT: {Name: "import", Help: "导入", Hand: func(m *ice.Message, arg ...string) {
_task_import(m, kit.Select(path.Join(EXPORT, m.Option(ice.MSG_DOMAIN), "list.csv"), arg, 0))
mdb.IMPORT: {Name: "import file", Help: "导入", Hand: func(m *ice.Message, arg ...string) {
_task_import(m, m.Option(kit.MDB_FILE))
}},
mdb.INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) {
_task_input(m, kit.Select("", arg, 0), kit.Select("", arg, 1))
_task_inputs(m, kit.Select("", arg, 0), kit.Select("", arg, 1))
}},
mdb.SEARCH: {Name: "search type name text", Help: "搜索", Hand: func(m *ice.Message, arg ...string) {
@ -188,18 +205,13 @@ func init() {
}},
gdb.BEGIN: {Name: "begin", Help: "开始", Hand: func(m *ice.Message, arg ...string) {
_task_modify(m, m.Option(kit.MDB_ZONE), m.Option(kit.MDB_ID), STATUS, StatusProcess)
_task_modify(m, m.Option(kit.MDB_ZONE), m.Option(kit.MDB_ID), TaskField.STATUS, TaskStatus.PROCESS)
}},
gdb.END: {Name: "end", Help: "完成", Hand: func(m *ice.Message, arg ...string) {
_task_modify(m, m.Option(kit.MDB_ZONE), m.Option(kit.MDB_ID), STATUS, StatusFinish)
_task_modify(m, m.Option(kit.MDB_ZONE), m.Option(kit.MDB_ID), TaskField.STATUS, TaskStatus.FINISH)
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Cmdy(mdb.SELECT, m.Prefix(TASK), m.Option(ice.MSG_DOMAIN), mdb.ZONE, arg)
if len(arg) > 0 {
m.Table(func(index int, value map[string]string, head []string) {
m.PushRender("action", "button", "", _task_action(m, value[STATUS])...)
})
}
_task_list(m, kit.Select("", arg, 0), kit.Select("", arg, 1))
}},
},
}, nil)

View File

@ -387,7 +387,9 @@ func init() {
arg = append(arg, kit.Select(ns[len(ns)-1], ""))
}
arg = _name(m, arg)
if len(arg) == 1 {
arg = append(arg, "")
}
_title_show(m, arg[0], kit.Select(arg[0], arg[1]), arg[2:]...)
}},
BRIEF: {Name: "brief [name] text", Help: "摘要", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {

16
init.go
View File

@ -97,7 +97,7 @@ var Index = &Context{Name: "ice", Help: "冰山模块",
m.root.Cmd(CTX_INIT)
m.target.root.wg = &sync.WaitGroup{}
for _, k := range kit.Split(kit.Select("gdb,log,ssh,ctx", os.Getenv("ctx_mod"))) {
for _, k := range kit.Split(kit.Select("gdb,log,ssh")) {
m.Start(k)
}
@ -186,20 +186,6 @@ func Run(arg ...string) string {
var names = map[string]interface{}{}
var ErrNameExists = "name already exists:"
type Error struct {
Arg []interface{}
FileLine string
}
func NewError(n int, arg ...interface{}) *Error {
return &Error{Arg: arg, FileLine: kit.FileLine(n, 3)}
}
func (e *Error) Error() string {
return e.FileLine + " " + strings.Join(kit.Simple(e.Arg), " ")
}
func Name(name string, value interface{}) string {
if s, ok := names[name]; ok {
last := ""

21
misc.go
View File

@ -89,8 +89,13 @@ func (m *Message) PushRender(key, view, name string, arg ...string) *Message {
return m
}
func (m *Message) PushAction(list ...interface{}) {
if len(m.meta[MSG_APPEND]) > 0 && m.meta[MSG_APPEND][0] == kit.MDB_KEY {
m.Push(kit.MDB_KEY, kit.MDB_ACTION)
m.PushRender(kit.MDB_VALUE, kit.MDB_BUTTON, strings.Join(kit.Simple(list...), ","))
return
}
m.Table(func(index int, value map[string]string, head []string) {
m.PushRender("action", "button", strings.Join(kit.Simple(list...), ","))
m.PushRender(kit.MDB_ACTION, kit.MDB_BUTTON, strings.Join(kit.Simple(list...), ","))
})
}
func (m *Message) PushDetail(value interface{}, arg ...interface{}) *Message {
@ -98,3 +103,17 @@ func (m *Message) PushDetail(value interface{}, arg ...interface{}) *Message {
}
var BinPack = map[string][]byte{}
var ErrNameExists = "name already exists:"
type Error struct {
Arg []interface{}
FileLine string
}
func (e *Error) Error() string {
return e.FileLine + " " + strings.Join(kit.Simple(e.Arg), " ")
}
func NewError(n int, arg ...interface{}) *Error {
return &Error{Arg: arg, FileLine: kit.FileLine(n, 3)}
}

View File

@ -63,7 +63,7 @@ var Index = &ice.Context{Name: ALPHA, Help: "英汉词典",
ALPHA: {Name: ALPHA, Help: "英汉词典", Value: kit.Data(
kit.MDB_LIMIT, "50000", kit.MDB_LEAST, "1000",
kit.MDB_STORE, "usr/export/alpha", kit.MDB_FSIZE, "2000000",
kit.MDB_REPOS, "word-dict", kit.MDB_FIELD, []interface{}{"audio", "bnc", "collins", "definition", "detail", "exchange", "frq", "id", "oxford", "phonetic", "pos", "tag", "time", "translation", "word"},
kit.SSH_REPOS, "word-dict", kit.MDB_FIELD, []interface{}{"audio", "bnc", "collins", "definition", "detail", "exchange", "frq", "id", "oxford", "phonetic", "pos", "tag", "time", "translation", "word"},
)},
},
Commands: map[string]*ice.Command{

View File

@ -65,7 +65,7 @@ func init() {
m.Cmdy(mdb.DELETE, m.Prefix(CACHE), "", 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, m.Prefix(CACHE), "", mdb.HASH, kit.MDB_STEP, "100")
m.Cmdy(mdb.PRUNES, m.Prefix(CACHE), "", mdb.HASH, kit.SSH_STEP, "100")
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Option(ice.MSG_ACTION, "删除")

View File

@ -100,7 +100,7 @@ var Index = &ice.Context{Name: "mp", Help: "小程序",
case "upload":
msg := m.Cmd(web.CACHE, "upload")
m.Cmd(web.STORY, web.WATCH, msg.Append("data"), path.Join("usr/local/mp/", path.Base(msg.Append("name"))))
m.Cmd(web.FAVOR, "device", "file", msg.Append("name"), msg.Append("data"))
// m.Cmd(web.FAVOR, "device", "file", msg.Append("name"), msg.Append("data"))
m.Render(msg.Append("data"))
case "cmds":

24
misc/vim/_trash.go Normal file
View File

@ -0,0 +1,24 @@
package vim
/*
m.Conf(web.FAVOR, "meta.render.vimrc", m.AddCmd(&ice.Command{Name: "render favor id", Help: "渲染引擎", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
value := m.Optionv("value").(map[string]interface{})
switch value["name"] {
case "read", "write", "exec":
p := path.Join(kit.Format(kit.Value(value, "extra.pwd")), kit.Format(kit.Value(value, "extra.buf")))
if strings.HasPrefix(kit.Format(kit.Value(value, "extra.buf")), "/") {
p = path.Join(kit.Format(kit.Value(value, "extra.buf")))
}
f, e := os.Open(p)
m.Assert(e)
defer f.Close()
b, e := ioutil.ReadAll(f)
m.Assert(e)
m.Echo(string(b))
default:
m.Cmdy(cli.SYSTEM, "sed", "-n", fmt.Sprintf("/%s/,/^}$/p", value["text"]), kit.Value(value, "extra.buf"))
}
}}))
*/

View File

@ -2,15 +2,12 @@ package vim
import (
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/cli"
"github.com/shylinux/icebergs/base/mdb"
"github.com/shylinux/icebergs/base/nfs"
"github.com/shylinux/icebergs/base/web"
"github.com/shylinux/icebergs/core/code"
kit "github.com/shylinux/toolkits"
"fmt"
"io/ioutil"
"os"
"path"
"strings"
@ -66,26 +63,6 @@ var Index = &ice.Context{Name: VIM, Help: "编辑器",
ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Load()
m.Conf(web.FAVOR, "meta.render.vimrc", m.AddCmd(&ice.Command{Name: "render favor id", Help: "渲染引擎", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
value := m.Optionv("value").(map[string]interface{})
switch value["name"] {
case "read", "write", "exec":
p := path.Join(kit.Format(kit.Value(value, "extra.pwd")), kit.Format(kit.Value(value, "extra.buf")))
if strings.HasPrefix(kit.Format(kit.Value(value, "extra.buf")), "/") {
p = path.Join(kit.Format(kit.Value(value, "extra.buf")))
}
f, e := os.Open(p)
m.Assert(e)
defer f.Close()
b, e := ioutil.ReadAll(f)
m.Assert(e)
m.Echo(string(b))
default:
m.Cmdy(cli.SYSTEM, "sed", "-n", fmt.Sprintf("/%s/,/^}$/p", value["text"]), kit.Value(value, "extra.buf"))
}
}}))
m.Cmd(mdb.PLUGIN, mdb.CREATE, VIMRC, VIM, c.Cap(ice.CTX_FOLLOW))
m.Cmd(mdb.RENDER, mdb.CREATE, VIMRC, VIM, c.Cap(ice.CTX_FOLLOW))
m.Cmd(mdb.PLUGIN, mdb.CREATE, VIM, VIM, c.Cap(ice.CTX_FOLLOW))