forked from x/icebergs
opt base
This commit is contained in:
parent
356d3b1670
commit
a564821a6a
@ -32,8 +32,7 @@ func init() {
|
||||
}
|
||||
content := []byte(kit.JoinKV(DF, NL, "From", m.Option(USERNAME), "To", m.Option(TO), "Subject", m.Option(SUBJECT), "Content-Type", "text/html; charset=UTF-8") + NL + NL + m.Option(CONTENT))
|
||||
auth := smtp.PlainAuth("", m.Option(USERNAME), m.Option(PASSWORD), kit.Split(m.Option(SERVICE), ice.DF)[0])
|
||||
m.Warn(smtp.SendMail(m.Option(SERVICE), auth, m.Option(USERNAME), kit.Split(m.Option(TO)), content))
|
||||
m.Logs(EMAIL, SEND, string(content))
|
||||
m.Logs(EMAIL, SEND, string(content)).Warn(smtp.SendMail(m.Option(SERVICE), auth, m.Option(USERNAME), kit.Split(m.Option(TO)), content))
|
||||
}},
|
||||
}, mdb.HashAction(mdb.SHORT, mdb.NAME, mdb.FIELD, "time,name,service,username,password", ice.ACTION, SEND))},
|
||||
})
|
||||
|
@ -2,7 +2,6 @@ package aaa
|
||||
|
||||
import (
|
||||
ice "shylinux.com/x/icebergs"
|
||||
"shylinux.com/x/icebergs/base/gdb"
|
||||
"shylinux.com/x/icebergs/base/mdb"
|
||||
kit "shylinux.com/x/toolkits"
|
||||
)
|
||||
@ -17,9 +16,9 @@ func init() {
|
||||
Index.MergeCommands(ice.Commands{
|
||||
OFFER: {Name: "offer hash auto", Help: "邀请", Actions: ice.MergeActions(ice.Actions{
|
||||
INVITE: {Name: "invite email*='shylinux@163.com' subject content", Help: "邀请", Hand: func(m *ice.Message, arg ...string) {
|
||||
h := mdb.HashCreate(m.Spawn(), m.OptionSimple(EMAIL, SUBJECT, CONTENT), "from", m.Option(ice.MSG_USERNAME), mdb.STATUS, INVITE)
|
||||
h := mdb.HashCreate(m.Spawn(), m.OptionSimple(EMAIL, SUBJECT, CONTENT), INVITE, m.Option(ice.MSG_USERNAME), mdb.STATUS, INVITE)
|
||||
m.Cmd(EMAIL, SEND, m.Option(EMAIL), m.OptionDefault(SUBJECT, "welcome to contents, please continue"),
|
||||
m.OptionDefault(CONTENT, ice.Render(m, ice.RENDER_ANCHOR, m.Cmdx("host", "publish", m.MergePodCmd("", "", mdb.HASH, h, gdb.DEBUG, ice.TRUE)))),
|
||||
m.OptionDefault(CONTENT, ice.Render(m, ice.RENDER_ANCHOR, m.Cmdx("host", "publish", m.MergePodCmd("", "", mdb.HASH, h)))),
|
||||
)
|
||||
}},
|
||||
ACCEPT: {Help: "接受", Hand: func(m *ice.Message, arg ...string) {
|
||||
@ -29,11 +28,11 @@ func init() {
|
||||
msg := m.Cmd("", m.Option(mdb.HASH))
|
||||
if ls := kit.Split(msg.Append(EMAIL), ice.AT); !m.Warn(msg.Length() == 0 || len(ls) < 2, ice.ErrNotValid, m.Option(mdb.HASH)) {
|
||||
m.Cmd(USER, mdb.CREATE, USERNICK, ls[0], USERNAME, msg.Append(EMAIL), USERZONE, ls[1])
|
||||
m.ProcessOpen(kit.MergeURL2(m.Option(ice.MSG_USERWEB), ice.PS, ice.MSG_SESSID, SessCreate(m, msg.Append(EMAIL)), mdb.HASH, "", gdb.DEBUG, ice.TRUE))
|
||||
m.ProcessOpen(kit.MergeURL2(m.Option(ice.MSG_USERWEB), ice.PS, ice.MSG_SESSID, SessCreate(m, msg.Append(EMAIL)), mdb.HASH, ""))
|
||||
mdb.HashModify(m, m.OptionSimple(mdb.HASH), mdb.STATUS, ACCEPT)
|
||||
}
|
||||
}},
|
||||
}, mdb.HashAction(mdb.SHORT, mdb.UNIQ, mdb.FIELD, "time,hash,status,from,email,title,content"), RoleAction(ACCEPT)), Hand: func(m *ice.Message, arg ...string) {
|
||||
}, mdb.HashAction(mdb.SHORT, mdb.UNIQ, mdb.FIELD, "time,hash,status,invite,email,title,content"), RoleAction(ACCEPT)), Hand: func(m *ice.Message, arg ...string) {
|
||||
if !m.Warn(len(arg) == 0 && m.Option(ice.MSG_USERROLE) == VOID, ice.ErrNotRight) {
|
||||
kit.If(mdb.HashSelect(m, arg...).FieldsIsDetail(), func() { m.PushAction(ACCEPT) }, func() { m.Action(INVITE) })
|
||||
}
|
||||
|
@ -50,6 +50,10 @@ func SessCheck(m *ice.Message, sessid string) bool {
|
||||
return sessid != "" && m.Cmdy(SESS, CHECK, sessid, logs.FileLineMeta(-1)).Option(ice.MSG_USERNAME) != ""
|
||||
}
|
||||
func SessAuth(m *ice.Message, value ice.Any, arg ...string) *ice.Message {
|
||||
switch val := value.(type) {
|
||||
case []string:
|
||||
value = kit.Dict(USERNICK, kit.Select("", val, 0), USERNAME, kit.Select("", val, 1), USERROLE, kit.Select("", val, 2))
|
||||
}
|
||||
return m.Auth(
|
||||
USERNICK, m.Option(ice.MSG_USERNICK, kit.Value(value, USERNICK)),
|
||||
USERNAME, m.Option(ice.MSG_USERNAME, kit.Value(value, USERNAME)),
|
||||
|
78
base/cli/color.go
Normal file
78
base/cli/color.go
Normal file
@ -0,0 +1,78 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"image/color"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
ice "shylinux.com/x/icebergs"
|
||||
kit "shylinux.com/x/toolkits"
|
||||
)
|
||||
|
||||
const (
|
||||
_DARK = 255
|
||||
_LIGHT = 127
|
||||
)
|
||||
|
||||
var _color_map = map[string]color.Color{
|
||||
BLACK: color.RGBA{0, 0, 0, _DARK},
|
||||
RED: color.RGBA{_DARK, 0, 0, _DARK},
|
||||
GREEN: color.RGBA{0, _DARK, 0, _DARK},
|
||||
YELLOW: color.RGBA{_DARK, _DARK, 0, _DARK},
|
||||
BLUE: color.RGBA{0, 0, _DARK, _DARK},
|
||||
PURPLE: color.RGBA{_DARK, 0, _DARK, _DARK},
|
||||
CYAN: color.RGBA{0, _DARK, _DARK, _DARK},
|
||||
WHITE: color.RGBA{_DARK, _DARK, _DARK, _DARK},
|
||||
}
|
||||
|
||||
func _parse_color(str string) color.Color {
|
||||
if str == RANDOM {
|
||||
list := kit.SortedKey(_color_map)
|
||||
str = list[rand.Intn(len(list))]
|
||||
}
|
||||
if strings.HasPrefix(str, "#") {
|
||||
kit.If(len(str) == 7, func() { str += "ff" })
|
||||
if u, e := strconv.ParseUint(str[1:], 16, 64); e == nil {
|
||||
return color.RGBA{uint8((u & 0xFF000000) >> 24), uint8((u & 0x00FF0000) >> 16), uint8((u & 0x0000FF00) >> 8), uint8((u & 0x000000FF) >> 0)}
|
||||
}
|
||||
}
|
||||
return _color_map[str]
|
||||
}
|
||||
func _parse_cli_color(str string) string {
|
||||
res := 0
|
||||
r, g, b, _ := _parse_color(str).RGBA()
|
||||
kit.If(r > _LIGHT, func() { res += 1 })
|
||||
kit.If(g > _LIGHT, func() { res += 2 })
|
||||
kit.If(b > _LIGHT, func() { res += 4 })
|
||||
return kit.Format(res)
|
||||
}
|
||||
|
||||
const (
|
||||
BG = "bg"
|
||||
FG = "fg"
|
||||
COLOR = "color"
|
||||
BLACK = "black"
|
||||
WHITE = "white"
|
||||
BLUE = "blue"
|
||||
RED = "red"
|
||||
GRAY = "gray"
|
||||
CYAN = "cyan"
|
||||
GREEN = "green"
|
||||
PURPLE = "purple"
|
||||
YELLOW = "yellow"
|
||||
RANDOM = "random"
|
||||
GLASS = "#0000"
|
||||
)
|
||||
|
||||
func Color(m *ice.Message, c string, str ice.Any) string {
|
||||
wrap, color := `<span style="color:%s">%v</span>`, c
|
||||
kit.If(m.IsCliUA(), func() { wrap, color = "\033[3%sm%v\033[0m", _parse_cli_color(c) })
|
||||
return fmt.Sprintf(wrap, color, str)
|
||||
}
|
||||
func ColorRed(m *ice.Message, str ice.Any) string { return Color(m, RED, str) }
|
||||
func ColorGreen(m *ice.Message, str ice.Any) string { return Color(m, GREEN, str) }
|
||||
func ColorYellow(m *ice.Message, str ice.Any) string { return Color(m, YELLOW, str) }
|
||||
func ParseCliColor(color string) string { return _parse_cli_color(color) }
|
||||
func ParseColor(color string) color.Color { return _parse_color(color) }
|
@ -4,7 +4,6 @@ import (
|
||||
"io"
|
||||
"os/exec"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
ice "shylinux.com/x/icebergs"
|
||||
"shylinux.com/x/icebergs/base/ctx"
|
||||
@ -24,8 +23,8 @@ func _daemon_exec(m *ice.Message, cmd *exec.Cmd) {
|
||||
if w := _system_out(m, CMD_ERRPUT); w != nil {
|
||||
cmd.Stderr = w
|
||||
}
|
||||
h := mdb.HashCreate(m.Spawn(), ice.CMD, kit.Join(cmd.Args, ice.SP),
|
||||
STATUS, START, DIR, cmd.Dir, ENV, kit.Select("", cmd.Env),
|
||||
h := mdb.HashCreate(m.Spawn(), STATUS, START,
|
||||
ice.CMD, kit.Join(cmd.Args, ice.SP), DIR, cmd.Dir, ENV, kit.Select("", cmd.Env),
|
||||
m.OptionSimple(CMD_INPUT, CMD_OUTPUT, CMD_ERRPUT, mdb.CACHE_CLEAR_ON_EXIT),
|
||||
)
|
||||
if e := cmd.Start(); m.Warn(e, ice.ErrNotStart, cmd.Args) {
|
||||
@ -36,21 +35,14 @@ func _daemon_exec(m *ice.Message, cmd *exec.Cmd) {
|
||||
m.Echo("%d", cmd.Process.Pid)
|
||||
m.Go(func() {
|
||||
if e := cmd.Wait(); !m.Warn(e, ice.ErrNotStart, cmd.Args) && cmd.ProcessState != nil && cmd.ProcessState.Success() {
|
||||
m.Cost(CODE, "0", ctx.ARGS, cmd.Args)
|
||||
mdb.HashModify(m, mdb.HASH, h, STATUS, STOP)
|
||||
m.Cost(CODE, "0", ctx.ARGS, cmd.Args)
|
||||
} else {
|
||||
mdb.HashSelectUpdate(m, h, func(value ice.Map) {
|
||||
if value[STATUS] == START {
|
||||
value[STATUS], value[ERROR] = ERROR, e
|
||||
}
|
||||
})
|
||||
mdb.HashSelectUpdate(m, h, func(value ice.Map) { kit.If(value[STATUS] == START, func() { value[STATUS], value[ERROR] = ERROR, e }) })
|
||||
}
|
||||
status := mdb.HashSelectField(m, h, STATUS)
|
||||
switch m.Sleep300ms(); cb := m.OptionCB("").(type) {
|
||||
switch status := mdb.HashSelectField(m.Sleep300ms(), h, STATUS); cb := m.OptionCB("").(type) {
|
||||
case func(string) bool:
|
||||
if !cb(status) {
|
||||
m.Cmdy(DAEMON, cmd.Path, cmd.Args)
|
||||
}
|
||||
kit.If(!cb(status), func() { m.Cmdy(DAEMON, cmd.Path, cmd.Args) })
|
||||
case func(string):
|
||||
cb(status)
|
||||
case func():
|
||||
@ -107,20 +99,15 @@ const DAEMON = "daemon"
|
||||
func init() {
|
||||
Index.MergeCommands(ice.Commands{
|
||||
DAEMON: {Name: "daemon hash auto", Help: "守护进程", Actions: ice.MergeActions(ice.Actions{
|
||||
ice.CTX_EXIT: {Hand: func(m *ice.Message, arg ...string) {
|
||||
mdb.HashPrunesValue(m, mdb.CACHE_CLEAR_ON_EXIT, ice.TRUE)
|
||||
}},
|
||||
ice.CTX_EXIT: {Hand: func(m *ice.Message, arg ...string) { mdb.HashPrunesValue(m, mdb.CACHE_CLEAR_ON_EXIT, ice.TRUE) }},
|
||||
START: {Name: "start cmd* dir env", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Options(CMD_DIR, m.Option(DIR), CMD_ENV, kit.Split(m.Option(ENV), " ="))
|
||||
_daemon_exec(m, _system_cmd(m, kit.Split(m.Option(ice.CMD))...))
|
||||
}},
|
||||
RESTART: {Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmdy("", STOP).Sleep3s().Cmdy("", START)
|
||||
}},
|
||||
RESTART: {Hand: func(m *ice.Message, arg ...string) { m.Cmdy("", STOP).Sleep3s().Cmdy("", START) }},
|
||||
STOP: {Hand: func(m *ice.Message, arg ...string) {
|
||||
m.OptionFields(mdb.HashField(m))
|
||||
h, pid := m.Option(mdb.HASH), m.Option(PID)
|
||||
mdb.HashSelect(m, m.Option(mdb.HASH)).Table(func(value ice.Maps) {
|
||||
mdb.HashSelects(m, h).Table(func(value ice.Maps) {
|
||||
if h == "" && value[PID] != pid {
|
||||
return
|
||||
}
|
||||
@ -129,23 +116,18 @@ func init() {
|
||||
})
|
||||
}},
|
||||
}, mdb.StatusHashAction(mdb.FIELD, "time,hash,status,pid,cmd,dir,env")), Hand: func(m *ice.Message, arg ...string) {
|
||||
if len(arg) == 0 || !strings.Contains(arg[0], ice.PS) {
|
||||
if mdb.HashSelect(m, kit.Slice(arg, 0, 1)...).Table(func(value ice.Maps) {
|
||||
switch value[STATUS] {
|
||||
case START:
|
||||
m.PushButton(RESTART, STOP)
|
||||
default:
|
||||
m.PushButton(START, mdb.REMOVE)
|
||||
}
|
||||
}); len(arg) == 0 || m.Length() > 0 {
|
||||
if len(arg) == 0 {
|
||||
m.Action(START, mdb.PRUNES)
|
||||
}
|
||||
return
|
||||
mdb.HashSelect(m, arg...).Table(func(value ice.Maps) {
|
||||
switch value[STATUS] {
|
||||
case START:
|
||||
m.PushButton(RESTART, STOP)
|
||||
default:
|
||||
m.PushButton(START, mdb.REMOVE)
|
||||
}
|
||||
}
|
||||
if _daemon_exec(m, _system_cmd(m, kit.Simple(kit.Split(arg[0]), arg[1:])...)); IsSuccess(m) && m.Append(CMD_ERR) == "" {
|
||||
m.SetAppend()
|
||||
})
|
||||
kit.If(len(arg) == 0, func() { m.Action(START, mdb.PRUNES) })
|
||||
if len(arg) > 0 && m.Length() == 0 {
|
||||
_daemon_exec(m, _system_cmd(m, kit.Simple(kit.Split(arg[0]), arg[1:])...))
|
||||
kit.If(IsSuccess(m) && m.Append(CMD_ERR) == "", func() { m.SetAppend() })
|
||||
}
|
||||
}},
|
||||
})
|
||||
|
@ -11,17 +11,17 @@ import (
|
||||
"shylinux.com/x/toolkits/logs"
|
||||
)
|
||||
|
||||
func _path_sep() string {
|
||||
return kit.Select(":", ";", strings.Contains(os.Getenv(PATH), ";"))
|
||||
}
|
||||
func _path_sep() string { return kit.Select(ice.DF, ";", strings.Contains(os.Getenv(PATH), ";")) }
|
||||
func BinPath(arg ...string) string {
|
||||
list := []string{}
|
||||
push := func(p string) { kit.If(kit.IndexOf(list, p) == -1, func() { list = append(list, p) }) }
|
||||
push := func(p string) {
|
||||
kit.If(kit.IndexOf(list, p) == -1, func() { list = append(list, kit.ReplaceAll(p, "\\", ice.PS)) })
|
||||
}
|
||||
kit.For(arg, func(p string) {
|
||||
list = append(list, kit.Path(p, ice.BIN), kit.Path(p, ice.USR_PUBLISH), kit.Path(p, ice.USR_LOCAL_BIN), kit.Path(p, ice.USR_LOCAL_GO_BIN))
|
||||
for _, l := range kit.Reverse(strings.Split(ice.Pulse.Cmdx(nfs.CAT, kit.Path(p, ice.ETC_PATH)), ice.NL)) {
|
||||
kit.For(kit.Reverse(strings.Split(ice.Pulse.Cmdx(nfs.CAT, kit.Path(p, ice.ETC_PATH)), ice.NL)), func(l string) {
|
||||
kit.If(strings.TrimSpace(l) != "" && !strings.HasPrefix(strings.TrimSpace(l), "#"), func() { push(kit.Path(p, l)) })
|
||||
}
|
||||
})
|
||||
})
|
||||
kit.For(strings.Split(kit.Env(PATH), _path_sep()), func(p string) { push(p) })
|
||||
return kit.Join(list, _path_sep())
|
||||
@ -35,22 +35,18 @@ func init() {
|
||||
START: {Hand: func(m *ice.Message, arg ...string) {
|
||||
env := []string{PATH, BinPath(""), HOME, kit.Select(kit.Path(""), os.Getenv(HOME))}
|
||||
kit.For(ENV_LIST, func(k string) { kit.If(kit.Env(k) != "", func() { env = append(env, k, kit.Env(k)) }) })
|
||||
for _, v := range os.Environ() {
|
||||
kit.For(os.Environ(), func(v string) {
|
||||
if ls := kit.Split(v, ice.EQ, ice.EQ); kit.IndexOf(env, ls[0]) == -1 && len(ls) > 1 {
|
||||
env = append(env, ls[0], ls[1])
|
||||
}
|
||||
}
|
||||
})
|
||||
m.Options(CMD_ENV, env, CMD_INPUT, os.Stdin, CMD_OUTPUT, os.Stdout, CMD_ERRPUT, os.Stderr)
|
||||
if p := kit.Env(CTX_LOG); p != "" {
|
||||
m.Optionv(CMD_ERRPUT, p)
|
||||
}
|
||||
kit.If(kit.Env(CTX_LOG), func(p string) { m.Optionv(CMD_ERRPUT, p) })
|
||||
m.Cmd(FOREVER, STOP)
|
||||
if bin := kit.Select(os.Args[0], ice.BIN_ICE_BIN, nfs.ExistsFile(m, ice.BIN_ICE_BIN)); len(arg) > 0 && arg[0] == ice.SPACE {
|
||||
m.Cmdy(FOREVER, bin, ice.SPACE, "dial", ice.DEV, ice.OPS, arg[1:])
|
||||
m.Cmdy(FOREVER, bin, ice.SPACE, START, ice.DEV, ice.OPS, arg[1:])
|
||||
} else {
|
||||
if len(arg) == 0 || arg[0] != ice.DEV {
|
||||
arg = append([]string{ice.DEV, ""}, arg...)
|
||||
}
|
||||
kit.If(len(arg) == 0 || arg[0] != ice.DEV, func() { arg = append([]string{ice.DEV, ""}, arg...) })
|
||||
m.Cmdy(FOREVER, bin, ice.SERVE, START, arg)
|
||||
}
|
||||
}},
|
||||
@ -64,7 +60,7 @@ func init() {
|
||||
}
|
||||
for {
|
||||
if logs.Println("run %s", kit.Join(arg, ice.SP)); IsSuccess(m.Cmd(SYSTEM, arg)) {
|
||||
defer logs.Println(ice.EXIT)
|
||||
logs.Println(ice.EXIT)
|
||||
break
|
||||
}
|
||||
logs.Println()
|
||||
|
@ -30,9 +30,7 @@ func init() {
|
||||
CMD: {Name: "cmd cli osid", Hand: func(m *ice.Message, arg ...string) {
|
||||
osid := kit.Select(mdb.Conf(m, RUNTIME, kit.Keys(HOST, OSID)), m.Option(OSID))
|
||||
mdb.ZoneSelectCB(m, m.Option(CLI), func(value ice.Map) {
|
||||
if osid != "" && strings.Contains(osid, kit.Format(value[OSID])) {
|
||||
m.Cmdy(kit.Split(kit.Format(value[CMD])))
|
||||
}
|
||||
kit.If(strings.Contains(osid, kit.Format(value[OSID])), func() { m.Cmdy(kit.Split(kit.Format(value[CMD]))) })
|
||||
})
|
||||
}},
|
||||
ALPINE: {Name: "alpine cli cmd", Hand: func(m *ice.Message, arg ...string) { IsAlpine(m, arg...) }},
|
||||
@ -44,16 +42,13 @@ var _release = ""
|
||||
|
||||
func release(m *ice.Message) string {
|
||||
osid := runtime.GOOS
|
||||
if osid != "linux" {
|
||||
if osid != LINUX {
|
||||
return osid
|
||||
}
|
||||
m.Option(nfs.CAT_CONTENT, _release)
|
||||
_release = m.Cmdx(nfs.CAT, "/etc/os-release", kit.Dict(ice.MSG_USERROLE, aaa.ROOT), func(text string, _ int) string {
|
||||
if ls := kit.Split(text, ice.EQ); len(ls) > 1 {
|
||||
switch ls[0] {
|
||||
case "ID", "ID_LIKE":
|
||||
osid = strings.TrimSpace(ls[1] + ice.SP + osid)
|
||||
}
|
||||
kit.Switch(ls[0], []string{"ID", "ID_LIKE"}, func() { osid = strings.TrimSpace(ls[1] + ice.SP + osid) })
|
||||
}
|
||||
return text
|
||||
})
|
||||
@ -64,15 +59,19 @@ func insert(m *ice.Message, sys, cmd string, arg ...string) bool {
|
||||
return false
|
||||
}
|
||||
if len(arg) > 0 {
|
||||
m.Go(func() {
|
||||
m.Sleep300ms().Cmd(mdb.INSERT, kit.Keys(CLI, MIRRORS), "", mdb.ZONE, arg[0], OSID, sys, CMD, cmd+ice.SP+kit.Select(arg[0], arg, 1))
|
||||
})
|
||||
m.GoSleep("300ms", mdb.INSERT, kit.Keys(CLI, MIRRORS), "", mdb.ZONE, arg[0], OSID, sys, CMD, cmd+ice.SP+kit.Select(arg[0], arg, 1))
|
||||
}
|
||||
return true
|
||||
}
|
||||
func IsAlpine(m *ice.Message, arg ...string) bool { return insert(m, ALPINE, "system apk add", arg...) }
|
||||
func IsCentos(m *ice.Message, arg ...string) bool { return insert(m, CENTOS, "yum install -y", arg...) }
|
||||
func IsUbuntu(m *ice.Message, arg ...string) bool { return insert(m, UBUNTU, "apt get -y", arg...) }
|
||||
func IsAlpine(m *ice.Message, arg ...string) bool {
|
||||
return insert(m, ALPINE, "system apk add", arg...)
|
||||
}
|
||||
func IsCentos(m *ice.Message, arg ...string) bool {
|
||||
return insert(m, CENTOS, "system yum install -y", arg...)
|
||||
}
|
||||
func IsUbuntu(m *ice.Message, arg ...string) bool {
|
||||
return insert(m, UBUNTU, "system apt get -y", arg...)
|
||||
}
|
||||
func IsSystem(m *ice.Message, arg ...string) bool {
|
||||
return IsAlpine(m, arg...) || IsCentos(m, arg...) || IsUbuntu(m, arg...)
|
||||
}
|
||||
|
@ -2,70 +2,19 @@ package cli
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"image/color"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"shylinux.com/x/go-qrcode"
|
||||
ice "shylinux.com/x/icebergs"
|
||||
"shylinux.com/x/icebergs/base/mdb"
|
||||
"shylinux.com/x/icebergs/base/nfs"
|
||||
"shylinux.com/x/icebergs/base/tcp"
|
||||
"shylinux.com/x/icebergs/misc/qrcode"
|
||||
kit "shylinux.com/x/toolkits"
|
||||
)
|
||||
|
||||
var _color_map = map[string]color.Color{
|
||||
BLACK: color.RGBA{0, 0, 0, DARK},
|
||||
RED: color.RGBA{DARK, 0, 0, DARK},
|
||||
GREEN: color.RGBA{0, DARK, 0, DARK},
|
||||
YELLOW: color.RGBA{DARK, DARK, 0, DARK},
|
||||
BLUE: color.RGBA{0, 0, DARK, DARK},
|
||||
PURPLE: color.RGBA{DARK, 0, DARK, DARK},
|
||||
CYAN: color.RGBA{0, DARK, DARK, DARK},
|
||||
WHITE: color.RGBA{DARK, DARK, DARK, DARK},
|
||||
}
|
||||
|
||||
func _parse_color(str string) color.Color {
|
||||
if str == RANDOM {
|
||||
list := kit.SortedKey(_color_map)
|
||||
str = list[rand.Intn(len(list))]
|
||||
}
|
||||
if strings.HasPrefix(str, "#") {
|
||||
if len(str) == 7 {
|
||||
str += "ff"
|
||||
}
|
||||
if u, e := strconv.ParseUint(str[1:], 16, 64); e == nil {
|
||||
return color.RGBA{
|
||||
uint8((u & 0xFF000000) >> 24),
|
||||
uint8((u & 0x00FF0000) >> 16),
|
||||
uint8((u & 0x0000FF00) >> 8),
|
||||
uint8((u & 0x000000FF) >> 0),
|
||||
}
|
||||
}
|
||||
}
|
||||
return _color_map[str]
|
||||
}
|
||||
func _parse_cli_color(str string) string {
|
||||
res := 0
|
||||
r, g, b, _ := _parse_color(str).RGBA()
|
||||
if r > LIGHT {
|
||||
res += 1
|
||||
}
|
||||
if g > LIGHT {
|
||||
res += 2
|
||||
}
|
||||
if b > LIGHT {
|
||||
res += 4
|
||||
}
|
||||
return kit.Format(res)
|
||||
}
|
||||
func _qrcode_cli(m *ice.Message, text string) {
|
||||
qr, _ := qrcode.New(text, qrcode.Medium)
|
||||
fg := _parse_cli_color(m.Option(FG))
|
||||
bg := _parse_cli_color(m.Option(BG))
|
||||
data := qr.Bitmap()
|
||||
sc := qrcode.New(text)
|
||||
fg := ParseCliColor(m.Option(FG))
|
||||
bg := ParseCliColor(m.Option(BG))
|
||||
data := sc.Bitmap()
|
||||
for i, row := range data {
|
||||
if n := len(data); i < 3 || i >= n-3 {
|
||||
continue
|
||||
@ -81,35 +30,17 @@ func _qrcode_cli(m *ice.Message, text string) {
|
||||
m.Echo(text).Echo(ice.NL)
|
||||
}
|
||||
func _qrcode_web(m *ice.Message, text string) string {
|
||||
qr, _ := qrcode.New(text, qrcode.Medium)
|
||||
qr.ForegroundColor = _parse_color(m.Option(FG))
|
||||
qr.BackgroundColor = _parse_color(m.Option(BG))
|
||||
if data, err := qr.PNG(kit.Int(m.Option(SIZE))); m.Assert(err) {
|
||||
sc := qrcode.New(text)
|
||||
sc.ForegroundColor = ParseColor(m.Option(FG))
|
||||
sc.BackgroundColor = ParseColor(m.Option(BG))
|
||||
if data, err := sc.PNG(kit.Int(m.Option(SIZE))); m.Assert(err) {
|
||||
m.Echo(`<img src="data:image/png;base64,%s" title='%s'>`, base64.StdEncoding.EncodeToString(data), text)
|
||||
}
|
||||
return text
|
||||
}
|
||||
|
||||
const (
|
||||
BG = "bg"
|
||||
FG = "fg"
|
||||
DARK = 255
|
||||
LIGHT = 127
|
||||
SIZE = "size"
|
||||
)
|
||||
const (
|
||||
COLOR = "color"
|
||||
BLACK = "black"
|
||||
WHITE = "white"
|
||||
BLUE = "blue"
|
||||
RED = "red"
|
||||
GRAY = "gray"
|
||||
CYAN = "cyan"
|
||||
GREEN = "green"
|
||||
PURPLE = "purple"
|
||||
YELLOW = "yellow"
|
||||
RANDOM = "random"
|
||||
GLASS = "#0000"
|
||||
SIZE = "size"
|
||||
)
|
||||
const QRCODE = "qrcode"
|
||||
|
||||
@ -124,7 +55,7 @@ func init() {
|
||||
mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) {
|
||||
switch arg[0] {
|
||||
case FG, BG:
|
||||
m.Push(arg[0], BLACK, WHITE, BLUE, RED, CYAN, GREEN, PURPLE, YELLOW)
|
||||
m.Push(arg[0], BLACK, WHITE)
|
||||
}
|
||||
}},
|
||||
}, Hand: func(m *ice.Message, arg ...string) {
|
||||
@ -140,23 +71,3 @@ func init() {
|
||||
}},
|
||||
})
|
||||
}
|
||||
|
||||
func Color(m *ice.Message, c string, str ice.Any) string {
|
||||
wrap, color := `<span style="color:%s">%v</span>`, c
|
||||
if m.IsCliUA() {
|
||||
wrap, color = "\033[3%sm%v\033[0m", _parse_cli_color(c)
|
||||
}
|
||||
return fmt.Sprintf(wrap, color, str)
|
||||
}
|
||||
func ColorRed(m *ice.Message, str ice.Any) string { return Color(m, RED, str) }
|
||||
func ColorGreen(m *ice.Message, str ice.Any) string { return Color(m, GREEN, str) }
|
||||
func ColorYellow(m *ice.Message, str ice.Any) string { return Color(m, YELLOW, str) }
|
||||
|
||||
func PushText(m *ice.Message, text string) {
|
||||
m.OptionFields(ice.MSG_DETAIL)
|
||||
if m.PushScript(nfs.SCRIPT, text); strings.HasPrefix(text, ice.HTTP) {
|
||||
m.PushQRCode(QRCODE, text)
|
||||
m.PushAnchor(text)
|
||||
}
|
||||
m.Echo(text)
|
||||
}
|
||||
|
@ -17,10 +17,7 @@ import (
|
||||
|
||||
func _runtime_init(m *ice.Message) {
|
||||
count := kit.Int(m.Conf(RUNTIME, kit.Keys(BOOT, mdb.COUNT)))
|
||||
kit.For(kit.UnMarshal(kit.Format(ice.Info.Make)), func(key string, value ice.Any) {
|
||||
m.Conf(RUNTIME, kit.Keys(MAKE, strings.ToLower(key)), value)
|
||||
})
|
||||
aaa.UserRoot(ice.Pulse, "", ice.Info.Make.Username, aaa.TECH, ice.DEV)
|
||||
kit.For(kit.UnMarshal(kit.Format(ice.Info.Make)), func(k string, v ice.Any) { m.Conf(RUNTIME, kit.Keys(MAKE, strings.ToLower(k)), v) })
|
||||
m.Conf(RUNTIME, kit.Keys(HOST, GOARCH), runtime.GOARCH)
|
||||
m.Conf(RUNTIME, kit.Keys(HOST, GOOS), runtime.GOOS)
|
||||
m.Conf(RUNTIME, kit.Keys(HOST, OSID), release(m))
|
||||
@ -28,22 +25,16 @@ func _runtime_init(m *ice.Message) {
|
||||
m.Conf(RUNTIME, kit.Keys(HOST, PWD), kit.Path(""))
|
||||
m.Conf(RUNTIME, kit.Keys(HOST, HOME), kit.HomePath(""))
|
||||
m.Conf(RUNTIME, kit.Keys(HOST, MAXPROCS), runtime.GOMAXPROCS(0))
|
||||
for _, k := range ENV_LIST {
|
||||
switch m.Conf(RUNTIME, kit.Keys(CONF, k), kit.Env(k)); k {
|
||||
case CTX_PID:
|
||||
ice.Info.PidPath = kit.Env(k)
|
||||
}
|
||||
}
|
||||
kit.For(ENV_LIST, func(k string) {
|
||||
m.Conf(RUNTIME, kit.Keys(CONF, k), kit.Env(k))
|
||||
kit.If(k == CTX_PID, func() { ice.Info.PidPath = kit.Env(k) })
|
||||
})
|
||||
m.Conf(RUNTIME, kit.Keys(BOOT, HOSTNAME), kit.Env("HOSTNAME"))
|
||||
if name, e := os.Hostname(); e == nil && name != "" {
|
||||
m.Conf(RUNTIME, kit.Keys(BOOT, HOSTNAME), name)
|
||||
}
|
||||
m.Conf(RUNTIME, kit.Keys(BOOT, PATHNAME), path.Base(kit.Path("")))
|
||||
m.Conf(RUNTIME, kit.Keys(BOOT, USERNAME), kit.Select(kit.UserName(), kit.Env(CTX_USER)))
|
||||
ice.Info.Hostname = m.Conf(RUNTIME, kit.Keys(BOOT, HOSTNAME))
|
||||
ice.Info.Pathname = m.Conf(RUNTIME, kit.Keys(BOOT, PATHNAME))
|
||||
ice.Info.Username = m.Conf(RUNTIME, kit.Keys(BOOT, USERNAME))
|
||||
aaa.UserRoot(ice.Pulse, "", ice.Info.Username, aaa.ROOT, ice.OPS)
|
||||
m.Conf(RUNTIME, kit.Keys(BOOT, USERNAME), kit.UserName())
|
||||
msg := m.Cmd(nfs.DIR, _system_find(m, os.Args[0]), "time,path,size,hash")
|
||||
m.Conf(RUNTIME, kit.Keys(BOOT, ice.BIN), msg.Append(nfs.PATH))
|
||||
m.Conf(RUNTIME, kit.Keys(BOOT, nfs.SIZE), msg.Append(nfs.SIZE))
|
||||
@ -52,6 +43,11 @@ func _runtime_init(m *ice.Message) {
|
||||
m.Conf(RUNTIME, kit.Keys(BOOT, mdb.COUNT), count+1)
|
||||
m.Conf(RUNTIME, mdb.META, "")
|
||||
m.Conf(RUNTIME, mdb.HASH, "")
|
||||
ice.Info.Hostname = m.Conf(RUNTIME, kit.Keys(BOOT, HOSTNAME))
|
||||
ice.Info.Pathname = m.Conf(RUNTIME, kit.Keys(BOOT, PATHNAME))
|
||||
ice.Info.Username = m.Conf(RUNTIME, kit.Keys(BOOT, USERNAME))
|
||||
aaa.UserRoot(ice.Pulse, "", ice.Info.Username, aaa.ROOT, ice.OPS)
|
||||
aaa.UserRoot(ice.Pulse, "", ice.Info.Make.Username, aaa.TECH, ice.DEV)
|
||||
}
|
||||
func _runtime_hostinfo(m *ice.Message) {
|
||||
m.Push("nCPU", strings.Count(m.Cmdx(nfs.CAT, "/proc/cpuinfo"), "processor"))
|
||||
@ -94,8 +90,8 @@ const (
|
||||
)
|
||||
const (
|
||||
PATH = "PATH"
|
||||
USER = "USER"
|
||||
HOME = "HOME"
|
||||
USER = "USER"
|
||||
TERM = "TERM"
|
||||
SHELL = "SHELL"
|
||||
)
|
||||
@ -104,21 +100,16 @@ const (
|
||||
CTX_COM = "ctx_com"
|
||||
CTX_DEV = "ctx_dev"
|
||||
CTX_OPS = "ctx_ops"
|
||||
CTX_POD = "ctx_pod"
|
||||
CTX_ARG = "ctx_arg"
|
||||
CTX_ENV = "ctx_env"
|
||||
CTX_PID = "ctx_pid"
|
||||
CTX_LOG = "ctx_log"
|
||||
CTX_POD = "ctx_pod"
|
||||
CTX_ENV = "ctx_env"
|
||||
|
||||
CTX_USER = "ctx_user"
|
||||
CTX_SHARE = "ctx_share"
|
||||
CTX_RIVER = "ctx_river"
|
||||
CTX_DAEMON = "ctx_daemon"
|
||||
|
||||
MAKE_DOMAIN = "make.domain"
|
||||
)
|
||||
|
||||
var ENV_LIST = []string{TERM, SHELL, CTX_SHY, CTX_COM, CTX_DEV, CTX_OPS, CTX_ARG, CTX_PID, CTX_USER, CTX_SHARE, CTX_RIVER, CTX_DAEMON}
|
||||
var ENV_LIST = []string{TERM, SHELL, CTX_SHY, CTX_COM, CTX_DEV, CTX_OPS, CTX_ARG, CTX_PID, CTX_DAEMON}
|
||||
|
||||
const (
|
||||
HOSTNAME = "hostname"
|
||||
@ -127,11 +118,11 @@ const (
|
||||
)
|
||||
const (
|
||||
IFCONFIG = "ifconfig"
|
||||
DISKINFO = "diskinfo"
|
||||
HOSTINFO = "hostinfo"
|
||||
USERINFO = "userinfo"
|
||||
PROCINFO = "procinfo"
|
||||
PROCKILL = "prockill"
|
||||
DISKINFO = "diskinfo"
|
||||
BOOTINFO = "bootinfo"
|
||||
MAXPROCS = "maxprocs"
|
||||
)
|
||||
@ -139,16 +130,17 @@ const RUNTIME = "runtime"
|
||||
|
||||
func init() {
|
||||
Index.MergeCommands(ice.Commands{
|
||||
RUNTIME: {Name: "runtime info=bootinfo,ifconfig,hostname,hostinfo,userinfo,procinfo,diskinfo,api,cli,cmd,env,path,chain auto", Help: "运行环境", Actions: ice.MergeActions(ice.Actions{
|
||||
RUNTIME: {Name: "runtime info=bootinfo,ifconfig,diskinfo,hostinfo,userinfo,procinfo,bootinfo,api,cli,cmd,env,path,chain auto", Help: "运行环境", Actions: ice.MergeActions(ice.Actions{
|
||||
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { _runtime_init(m) }},
|
||||
IFCONFIG: {Hand: func(m *ice.Message, arg ...string) { m.Cmdy("tcp.host") }},
|
||||
DISKINFO: {Hand: func(m *ice.Message, arg ...string) { _runtime_diskinfo(m) }},
|
||||
HOSTINFO: {Hand: func(m *ice.Message, arg ...string) { _runtime_hostinfo(m) }},
|
||||
HOSTNAME: {Hand: func(m *ice.Message, arg ...string) {
|
||||
if len(arg) > 0 {
|
||||
ice.Info.Hostname = mdb.Conf(m, RUNTIME, kit.Keys(BOOT, HOSTNAME), mdb.Conf(m, RUNTIME, kit.Keys(NODE, mdb.NAME), arg[0]))
|
||||
ice.Info.Hostname = mdb.Conf(m, RUNTIME, kit.Keys(NODE, mdb.NAME), mdb.Conf(m, RUNTIME, kit.Keys(BOOT, HOSTNAME), arg[0]))
|
||||
}
|
||||
m.Echo(ice.Info.Hostname)
|
||||
}},
|
||||
HOSTINFO: {Hand: func(m *ice.Message, arg ...string) { _runtime_hostinfo(m) }},
|
||||
USERINFO: {Hand: func(m *ice.Message, arg ...string) { m.Split(m.Cmdx(SYSTEM, "who"), "user term time") }},
|
||||
PROCINFO: {Hand: func(m *ice.Message, arg ...string) {
|
||||
msg := m.Cmd("", HOSTINFO)
|
||||
@ -160,14 +152,6 @@ func init() {
|
||||
kit.If(len(arg) > 0, func() { runtime.GOMAXPROCS(kit.Int(mdb.Conf(m, RUNTIME, kit.Keys(HOST, MAXPROCS), arg[0]))) })
|
||||
m.Echo("%d", runtime.GOMAXPROCS(0))
|
||||
}},
|
||||
DISKINFO: {Hand: func(m *ice.Message, arg ...string) { _runtime_diskinfo(m) }},
|
||||
MAKE_DOMAIN: {Hand: func(m *ice.Message, arg ...string) {
|
||||
if os.Getenv(CTX_DEV) == "" || os.Getenv(CTX_POD) == "" {
|
||||
m.Echo(mdb.Conf(m, RUNTIME, MAKE_DOMAIN))
|
||||
} else {
|
||||
m.Echo(kit.MergePOD(os.Getenv(CTX_DEV), os.Getenv(CTX_POD)))
|
||||
}
|
||||
}},
|
||||
API: {Hand: func(m *ice.Message, arg ...string) {
|
||||
kit.For(ice.Info.Route, func(k, v string) { m.Push(nfs.PATH, k).Push(nfs.FILE, v) })
|
||||
m.StatusTimeCount().Sort(nfs.PATH)
|
||||
|
@ -18,7 +18,7 @@ import (
|
||||
)
|
||||
|
||||
func _path_split(ps string) []string {
|
||||
ps = strings.ReplaceAll(ps, "\\", ice.PS)
|
||||
ps = kit.ReplaceAll(ps, "\\", ice.PS)
|
||||
return kit.Split(ps, ice.NL+kit.Select(ice.DF, ";", strings.Contains(ps, ";")), ice.NL)
|
||||
}
|
||||
func _system_cmd(m *ice.Message, arg ...string) *exec.Cmd {
|
||||
@ -69,8 +69,7 @@ func _system_out(m *ice.Message, out string) io.Writer {
|
||||
} else if m.Option(out) == "" {
|
||||
return nil
|
||||
} else if f, p, e := file.CreateFile(m.Option(out)); m.Assert(e) {
|
||||
m.Logs(nfs.SAVE, out, p)
|
||||
m.Optionv(out, f)
|
||||
m.Logs(nfs.SAVE, out, p).Optionv(out, f)
|
||||
return f
|
||||
}
|
||||
return nil
|
||||
@ -116,14 +115,12 @@ func _system_find(m Message, bin string, dir ...string) string {
|
||||
if strings.HasPrefix(bin, nfs.PWD) {
|
||||
return bin
|
||||
}
|
||||
if len(dir) == 0 {
|
||||
dir = append(dir, _path_split(kit.Env(PATH))...)
|
||||
}
|
||||
kit.If(len(dir) == 0, func() { dir = append(dir, _path_split(kit.Env(PATH))...) })
|
||||
for _, p := range dir {
|
||||
if nfs.ExistsFile(m, path.Join(p, bin)) {
|
||||
return kit.Path(p, bin)
|
||||
}
|
||||
if nfs.ExistsFile(m, path.Join(p, bin)+".exe") {
|
||||
if IsWindows() && nfs.ExistsFile(m, path.Join(p, bin)+".exe") {
|
||||
return kit.Path(p, bin) + ".exe"
|
||||
}
|
||||
}
|
||||
@ -145,11 +142,11 @@ const (
|
||||
CMD_OUT = "cmd_out"
|
||||
|
||||
MAN = "man"
|
||||
GREP = "grep"
|
||||
OPENS = "opens"
|
||||
REST = "rest"
|
||||
FIND = "find"
|
||||
GREP = "grep"
|
||||
EXEC = "exec"
|
||||
REST = "rest"
|
||||
OPENS = "opens"
|
||||
)
|
||||
|
||||
const SYSTEM = "system"
|
||||
@ -214,11 +211,10 @@ func SystemFind(m Message, bin string, dir ...string) string {
|
||||
if text := kit.ReadFile(ice.ETC_PATH); len(text) > 0 {
|
||||
dir = append(dir, strings.Split(text, ice.NL)...)
|
||||
}
|
||||
dir = append(dir, _path_split(kit.Env(PATH))...)
|
||||
return _system_find(m, bin, dir...)
|
||||
return _system_find(m, bin, append(dir, _path_split(kit.Env(PATH))...)...)
|
||||
}
|
||||
func IsSuccess(m Message) bool { return m.Append(CODE) == "" || m.Append(CODE) == "0" }
|
||||
func SystemExec(m *ice.Message, arg ...string) string { return strings.TrimSpace(m.Cmdx(SYSTEM, arg)) }
|
||||
func SystemCmds(m *ice.Message, cmds string, args ...ice.Any) string {
|
||||
return strings.TrimRight(m.Cmdx(SYSTEM, "sh", "-c", kit.Format(cmds, args...), ice.Option{CMD_OUTPUT, ""}), ice.NL)
|
||||
}
|
||||
func IsSuccess(m Message) bool { return m.Append(CODE) == "" || m.Append(CODE) == "0" }
|
||||
|
@ -6,4 +6,4 @@ const CTX = "ctx"
|
||||
|
||||
var Index = &ice.Context{Name: CTX, Help: "标准模块"}
|
||||
|
||||
func init() { ice.Index.Register(Index, nil, CONTEXT, COMMAND, CONFIG, MESSAGE, OPTION) }
|
||||
func init() { ice.Index.Register(Index, nil, CONTEXT, COMMAND, CONFIG) }
|
||||
|
@ -1,34 +0,0 @@
|
||||
package ctx
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
ice "shylinux.com/x/icebergs"
|
||||
"shylinux.com/x/icebergs/base/mdb"
|
||||
"shylinux.com/x/toolkits/logs"
|
||||
)
|
||||
|
||||
const OPTION = "option"
|
||||
const MESSAGE = "message"
|
||||
|
||||
func init() {
|
||||
Index.MergeCommands(ice.Commands{
|
||||
OPTION: {Name: "option", Help: "选项", Hand: func(m *ice.Message, arg ...string) {
|
||||
if len(arg) > 1 {
|
||||
if msg, ok := m.Optionv("message").(*ice.Message); ok {
|
||||
msg.Option(arg[0], arg[1])
|
||||
}
|
||||
}
|
||||
}},
|
||||
MESSAGE: {Name: "message auto", Help: "消息", Hand: func(m *ice.Message, arg ...string) {
|
||||
t := reflect.TypeOf(m)
|
||||
for i := 0; i < t.NumMethod(); i++ {
|
||||
method := t.Method(i)
|
||||
p := logs.FileLine(method.Func.Interface())
|
||||
m.Push(mdb.NAME, method.Name)
|
||||
m.Push(mdb.TEXT, strings.Split(p, ice.ICEBERGS+ice.PS)[1])
|
||||
}
|
||||
}},
|
||||
})
|
||||
}
|
@ -148,19 +148,19 @@ func CloseFile(m Message, p ice.Any) {
|
||||
}
|
||||
}
|
||||
|
||||
func CopyFile(m *ice.Message, to io.WriteCloser, from io.ReadCloser, bufs, total int, cb ice.Any) {
|
||||
size, buf := 0, make([]byte, bufs)
|
||||
func CopyFile(m *ice.Message, to io.WriteCloser, from io.ReadCloser, cache, total int, cb ice.Any) {
|
||||
count, buf := 0, make([]byte, cache)
|
||||
for {
|
||||
n, e := from.Read(buf)
|
||||
to.Write(buf[0:n])
|
||||
if size += n; size > total {
|
||||
total = size
|
||||
if count += n; count > total {
|
||||
total = count
|
||||
}
|
||||
switch step := size * 100 / total; cb := cb.(type) {
|
||||
switch value := count * 100 / total; cb := cb.(type) {
|
||||
case func(int, int, int):
|
||||
cb(size, total, step)
|
||||
cb(count, total, value)
|
||||
case func(int, int):
|
||||
cb(size, total)
|
||||
cb(count, total)
|
||||
case nil:
|
||||
default:
|
||||
m.ErrorNotImplement(cb)
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
|
||||
ice "shylinux.com/x/icebergs"
|
||||
"shylinux.com/x/icebergs/base/mdb"
|
||||
kit "shylinux.com/x/toolkits"
|
||||
)
|
||||
|
||||
type Conn struct {
|
||||
@ -34,9 +35,7 @@ func _client_dial(m *ice.Message, arg ...string) {
|
||||
}
|
||||
switch cb := m.OptionCB("").(type) {
|
||||
case func(net.Conn):
|
||||
if !m.Warn(e) {
|
||||
cb(c)
|
||||
}
|
||||
kit.If(!m.Warn(e), func() { cb(c) })
|
||||
default:
|
||||
m.ErrorNotImplement(cb)
|
||||
}
|
||||
|
@ -13,10 +13,7 @@ import (
|
||||
func _host_list(m *ice.Message, name string) {
|
||||
if ifs, e := net.Interfaces(); m.Assert(e) {
|
||||
for _, v := range ifs {
|
||||
if name != "" && !strings.Contains(v.Name, name) {
|
||||
continue
|
||||
}
|
||||
if len(v.HardwareAddr.String()) == 0 {
|
||||
if !strings.Contains(v.Name, name) || len(v.HardwareAddr.String()) == 0 {
|
||||
continue
|
||||
}
|
||||
if ips, e := v.Addrs(); m.Assert(e) {
|
||||
|
@ -40,7 +40,7 @@ func init() {
|
||||
BROAD: {Name: "broad hash auto", Help: "广播", Actions: ice.MergeActions(ice.Actions{
|
||||
mdb.SEARCH: {Hand: func(m *ice.Message, arg ...string) {
|
||||
if arg[0] == mdb.FOREACH && arg[1] == "" {
|
||||
host, domain := m.Cmdv(tcp.HOST, aaa.IP), OptionUserWeb(m).Hostname()
|
||||
host, domain := m.Cmdv(tcp.HOST, aaa.IP), UserWeb(m).Hostname()
|
||||
m.Cmds("", func(value ice.Maps) {
|
||||
switch kit.If(value[tcp.HOST] == host, func() { value[tcp.HOST] = domain }); value[mdb.TYPE] {
|
||||
case "sshd":
|
||||
@ -60,7 +60,3 @@ func init() {
|
||||
}, mdb.HashAction(mdb.SHORT, "host,port", mdb.FIELD, "time,hash,type,name,host,port", mdb.ACTION, OPEN), mdb.ClearOnExitHashAction())},
|
||||
})
|
||||
}
|
||||
func Domain(host, port string) string { return kit.Format("http://%s:%s", host, port) }
|
||||
func Script(m *ice.Message, str string, arg ...ice.Any) string {
|
||||
return ice.Render(m, ice.RENDER_SCRIPT, kit.Format(str, arg...))
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package web
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
@ -19,11 +18,11 @@ import (
|
||||
|
||||
func _cache_name(m *ice.Message, h string) string { return path.Join(ice.VAR_FILE, h[:2], h) }
|
||||
func _cache_mime(m *ice.Message, mime, name string) string {
|
||||
if mime == "application/octet-stream" {
|
||||
if mime == ApplicationOctet {
|
||||
if kit.ExtIsImage(name) {
|
||||
mime = "image/" + kit.Ext(name)
|
||||
mime = IMAGE + ice.PS + kit.Ext(name)
|
||||
} else if kit.ExtIsVideo(name) {
|
||||
mime = "video/" + kit.Ext(name)
|
||||
mime = VIDEO + ice.PS + kit.Ext(name)
|
||||
}
|
||||
} else if mime == "" {
|
||||
return kit.Ext(name)
|
||||
@ -64,7 +63,7 @@ func _cache_upload(m *ice.Message, r *http.Request) (mime, name, file, size stri
|
||||
defer f.Close()
|
||||
b.Seek(0, os.SEEK_SET)
|
||||
if n, e := io.Copy(f, b); !m.Warn(e, ice.ErrNotValid, UPLOAD) {
|
||||
m.Logs(nfs.LOAD, nfs.FILE, p, nfs.SIZE, kit.FmtSize(int64(n)))
|
||||
m.Logs(nfs.SAVE, nfs.FILE, p, nfs.SIZE, kit.FmtSize(int64(n)))
|
||||
return h.Header.Get(ContentType), h.Filename, p, kit.Format(n)
|
||||
}
|
||||
}
|
||||
@ -72,24 +71,21 @@ func _cache_upload(m *ice.Message, r *http.Request) (mime, name, file, size stri
|
||||
return "", "", "", "0"
|
||||
}
|
||||
func _cache_download(m *ice.Message, r *http.Response, file string, cb ice.Any) string {
|
||||
if f, p, e := nfs.CreateFile(m, file); m.Assert(e) {
|
||||
// if f, p, e := miss.CreateFile(file); !m.Warn(e, ice.ErrNotValid, DOWNLOAD) {
|
||||
if f, p, e := miss.CreateFile(file); !m.Warn(e, ice.ErrNotValid, DOWNLOAD) {
|
||||
defer f.Close()
|
||||
last, base := 0, 10
|
||||
nfs.CopyFile(m, f, r.Body, base*ice.MOD_BUFS, kit.Int(kit.Select("100", r.Header.Get(ContentLength))), func(count, total, step int) {
|
||||
if step/base != last {
|
||||
m.Logs(nfs.SAVE, nfs.FILE, p, mdb.COUNT, count, mdb.TOTAL, total, mdb.VALUE, step)
|
||||
switch cb := cb.(type) {
|
||||
case func(int, int, int):
|
||||
if cb != nil {
|
||||
cb(count, total, step)
|
||||
}
|
||||
case nil:
|
||||
default:
|
||||
m.ErrorNotImplement(cb)
|
||||
}
|
||||
nfs.CopyFile(m, f, r.Body, base*ice.MOD_BUFS, kit.Int(kit.Select("100", r.Header.Get(ContentLength))), func(count, total, value int) {
|
||||
if value/base == last {
|
||||
return
|
||||
}
|
||||
last = value / base
|
||||
switch m.Logs(nfs.SAVE, nfs.FILE, p, mdb.COUNT, count, mdb.TOTAL, total, mdb.VALUE, value); cb := cb.(type) {
|
||||
case func(int, int, int):
|
||||
kit.If(cb != nil, func() { cb(count, total, value) })
|
||||
case nil:
|
||||
default:
|
||||
m.ErrorNotImplement(cb)
|
||||
}
|
||||
last = step / base
|
||||
})
|
||||
return p
|
||||
}
|
||||
@ -102,13 +98,15 @@ const (
|
||||
WRITE = "write"
|
||||
UPLOAD = "upload"
|
||||
DOWNLOAD = "download"
|
||||
DISPLAY = "display"
|
||||
|
||||
IMAGE = "image"
|
||||
VIDEO = "video"
|
||||
)
|
||||
const CACHE = "cache"
|
||||
|
||||
func init() {
|
||||
Index.MergeCommands(ice.Commands{
|
||||
CACHE: {Name: "cache hash auto write catch upload", Help: "缓存池", Actions: ice.MergeActions(ice.Actions{
|
||||
CACHE: {Name: "cache hash auto write catch upload download", Help: "缓存池", Actions: ice.MergeActions(ice.Actions{
|
||||
WATCH: {Name: "watch hash* path*", Help: "释放", Hand: func(m *ice.Message, arg ...string) {
|
||||
_cache_watch(m, m.Option(mdb.HASH), m.Option(nfs.PATH))
|
||||
}},
|
||||
@ -124,16 +122,13 @@ func init() {
|
||||
_cache_save(m, mime, name, "", file, size)
|
||||
}},
|
||||
DOWNLOAD: {Name: "download type name*", Hand: func(m *ice.Message, arg ...string) {
|
||||
if r, ok := m.Optionv(RESPONSE).(*http.Response); !m.Warn(!ok, ice.ErrNotValid, RESPONSE) {
|
||||
file, size := _cache_catch(m, _cache_download(m, r, path.Join(ice.VAR_TMP, kit.Hashs(mdb.UNIQ)), m.OptionCB("")))
|
||||
if res, ok := m.Optionv(RESPONSE).(*http.Response); !m.Warn(!ok, ice.ErrNotValid, RESPONSE) {
|
||||
file, size := _cache_catch(m, _cache_download(m, res, path.Join(ice.VAR_TMP, kit.Hashs(mdb.UNIQ)), m.OptionCB("")))
|
||||
_cache_save(m, m.Option(mdb.TYPE), m.Option(mdb.NAME), "", file, size)
|
||||
}
|
||||
}},
|
||||
ice.RENDER_DOWNLOAD: {Hand: func(m *ice.Message, arg ...string) {
|
||||
p := kit.Select(arg[0], arg, 1)
|
||||
p = kit.Select("", SHARE_LOCAL, !strings.HasPrefix(p, ice.PS) && !strings.HasPrefix(p, HTTP)) + p
|
||||
args := []string{ice.POD, m.Option(ice.MSG_USERPOD), "filename", kit.Select("", arg[0], len(arg) > 1)}
|
||||
m.Echo(fmt.Sprintf(`<a href="%s" download="%s">%s</a>`, MergeURL2(m, p, args), path.Base(arg[0]), arg[0]))
|
||||
m.Echo(_share_link(m, kit.Select(arg[0], arg, 1), ice.POD, m.Option(ice.MSG_USERPOD), "filename", kit.Select("", arg[0], len(arg) > 1)))
|
||||
}},
|
||||
ice.PS: {Hand: func(m *ice.Message, arg ...string) {
|
||||
mdb.HashSelectDetail(m, arg[0], func(value ice.Map) {
|
||||
@ -145,13 +140,13 @@ func init() {
|
||||
})
|
||||
}},
|
||||
}, mdb.HashAction(mdb.SHORT, mdb.TEXT, mdb.FIELD, "time,hash,size,type,name,text,file", ctx.ACTION, WATCH), ice.RenderAction(ice.RENDER_DOWNLOAD)), Hand: func(m *ice.Message, arg ...string) {
|
||||
if mdb.HashSelect(m, arg...); len(arg) == 0 || m.R.Method == http.MethodGet {
|
||||
if mdb.HashSelect(m, arg...); len(arg) == 0 || m.R != nil && m.R.Method == http.MethodGet {
|
||||
return
|
||||
}
|
||||
if m.Append(nfs.FILE) == "" {
|
||||
m.PushScript(mdb.TEXT, m.Append(mdb.TEXT))
|
||||
} else {
|
||||
PushDisplay(m, m.Append(mdb.TYPE), m.Append(mdb.NAME), MergeURL2(m, SHARE_CACHE+arg[0]))
|
||||
PushDisplay(m, m.Append(mdb.TYPE), m.Append(mdb.NAME), MergeURL2(m, P(SHARE, CACHE, arg[0])))
|
||||
}
|
||||
}},
|
||||
})
|
||||
@ -167,13 +162,35 @@ func init() {
|
||||
m.Assert(len(up) > 1)
|
||||
m.Cmd(CACHE, m.Option(ice.MSG_UPLOAD)).Table(func(value ice.Maps) { m.Options(value) })
|
||||
if m.Options(mdb.HASH, up[0], mdb.NAME, up[1]); watch {
|
||||
m.Cmdy(CACHE, WATCH, m.Option(mdb.HASH), path.Join(m.Option(nfs.PATH), m.Option(mdb.NAME)))
|
||||
m.Cmdy(CACHE, WATCH, m.Option(mdb.HASH), path.Join(m.Option(nfs.PATH), up[1]))
|
||||
}
|
||||
}, action.Hand)
|
||||
}
|
||||
})
|
||||
ctx.Upload = Upload
|
||||
}
|
||||
func Upload(m *ice.Message) []string {
|
||||
if up := kit.Simple(m.Optionv(ice.MSG_UPLOAD)); len(up) == 1 {
|
||||
if m.Cmdy(CACHE, UPLOAD).Optionv(ice.MSG_UPLOAD, kit.Simple(m.Append(mdb.HASH), m.Append(mdb.NAME), m.Append(nfs.SIZE))); m.Option(ice.MSG_USERPOD) != "" {
|
||||
m.Cmd(SPACE, m.Option(ice.MSG_USERPOD), SPIDE, ice.DEV, SPIDE_CACHE, http.MethodGet, tcp.PublishLocalhost(m, MergeURL2(m, PP(SHARE, CACHE, m.Append(mdb.HASH)))))
|
||||
}
|
||||
return kit.Simple(m.Optionv(ice.MSG_UPLOAD))
|
||||
} else {
|
||||
return up
|
||||
}
|
||||
}
|
||||
func Download(m *ice.Message, link string, cb func(count, total, value int)) *ice.Message {
|
||||
return m.Cmdy(Prefix(SPIDE), ice.DEV, SPIDE_CACHE, http.MethodGet, link, cb)
|
||||
}
|
||||
func PushDisplay(m *ice.Message, mime, name, link string) {
|
||||
if strings.HasPrefix(mime, IMAGE+ice.PS) || kit.ExtIsImage(name) {
|
||||
m.PushImages(nfs.FILE, link)
|
||||
} else if strings.HasPrefix(mime, VIDEO+ice.PS) || kit.ExtIsImage(name) {
|
||||
m.PushVideos(nfs.FILE, link)
|
||||
} else {
|
||||
m.PushDownload(nfs.FILE, name, link)
|
||||
}
|
||||
}
|
||||
func RenderCache(m *ice.Message, h string) {
|
||||
if msg := m.Cmd(CACHE, h); msg.Append(nfs.FILE) == "" {
|
||||
m.RenderResult(msg.Append(mdb.TEXT))
|
||||
@ -181,25 +198,3 @@ func RenderCache(m *ice.Message, h string) {
|
||||
m.RenderDownload(msg.Append(mdb.FILE), msg.Append(mdb.TYPE), msg.Append(mdb.NAME))
|
||||
}
|
||||
}
|
||||
func Upload(m *ice.Message) []string {
|
||||
if up := kit.Simple(m.Optionv(ice.MSG_UPLOAD)); len(up) == 1 {
|
||||
if m.Cmdy(CACHE, UPLOAD).Optionv(ice.MSG_UPLOAD, kit.Simple(m.Append(mdb.HASH), m.Append(mdb.NAME), m.Append(nfs.SIZE))); m.Option(ice.MSG_USERPOD) != "" {
|
||||
m.Cmd(SPACE, m.Option(ice.MSG_USERPOD), SPIDE, ice.DEV, SPIDE_CACHE, http.MethodGet, tcp.PublishLocalhost(m, MergeURL2(m, path.Join(SHARE_CACHE, m.Append(mdb.HASH)))))
|
||||
}
|
||||
return kit.Simple(m.Optionv(ice.MSG_UPLOAD))
|
||||
} else {
|
||||
return up
|
||||
}
|
||||
}
|
||||
func Download(m *ice.Message, link string, cb func(count, total, value int)) *ice.Message {
|
||||
return m.Cmdy("web.spide", ice.DEV, SPIDE_CACHE, http.MethodGet, link, cb)
|
||||
}
|
||||
func PushDisplay(m *ice.Message, mime, name, link string) {
|
||||
if strings.HasPrefix(mime, "image/") || kit.ExtIsImage(name) {
|
||||
m.PushImages(nfs.FILE, link)
|
||||
} else if strings.HasPrefix(mime, "video/") || kit.ExtIsImage(name) {
|
||||
m.PushVideos(nfs.FILE, link)
|
||||
} else {
|
||||
m.PushDownload(nfs.FILE, name, link)
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ func _dream_show(m *ice.Message, name string) {
|
||||
return
|
||||
}
|
||||
kit.If(!strings.Contains(name, "-") || !strings.HasPrefix(name, "20"), func() { name = m.Time("20060102-") + name })
|
||||
defer m.ProcessOpen(MergePods(m, m.Option(mdb.NAME, name)))
|
||||
defer m.ProcessOpen(m.MergePod(m.Option(mdb.NAME, name)))
|
||||
p := path.Join(ice.USR_LOCAL_WORK, name)
|
||||
if pid := m.Cmdx(nfs.CAT, path.Join(p, ice.Info.PidPath), kit.Dict(ice.MSG_USERROLE, aaa.TECH)); pid != "" && nfs.ExistsFile(m, "/proc/"+pid) {
|
||||
m.Info("already exists %v", pid)
|
||||
@ -93,7 +93,7 @@ func init() {
|
||||
DREAM: {Name: "dream name path auto create", Help: "梦想家", Actions: ice.MergeActions(ice.Actions{
|
||||
mdb.SEARCH: {Hand: func(m *ice.Message, arg ...string) {
|
||||
if arg[0] == mdb.FOREACH && arg[1] == "" {
|
||||
m.Cmds("", func(value ice.Maps) { m.PushSearch(mdb.TEXT, MergePods(m, value[mdb.NAME]), value) })
|
||||
m.Cmds("", func(value ice.Maps) { m.PushSearch(mdb.TEXT, m.MergePod(value[mdb.NAME]), value) })
|
||||
}
|
||||
}},
|
||||
mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) {
|
||||
@ -136,7 +136,7 @@ func init() {
|
||||
DREAM_TABLES: {Hand: func(m *ice.Message, arg ...string) {
|
||||
kit.Switch(m.Option(mdb.TYPE), []string{SERVER, WORKER}, func() { m.PushButton(OPEN) })
|
||||
}},
|
||||
OPEN: {Hand: func(m *ice.Message, arg ...string) { ctx.ProcessOpen(m, MergePods(m, m.Option(mdb.NAME), arg)) }},
|
||||
OPEN: {Hand: func(m *ice.Message, arg ...string) { ctx.ProcessOpen(m, m.MergePod(m.Option(mdb.NAME), arg)) }},
|
||||
}, ctx.CmdAction(), DreamAction()), Hand: func(m *ice.Message, arg ...string) {
|
||||
if len(arg) == 0 {
|
||||
_dream_list(m)
|
||||
|
@ -2,7 +2,6 @@ package web
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"path"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@ -10,48 +9,77 @@ import (
|
||||
"shylinux.com/x/icebergs/base/aaa"
|
||||
"shylinux.com/x/icebergs/base/cli"
|
||||
"shylinux.com/x/icebergs/base/ctx"
|
||||
"shylinux.com/x/icebergs/base/gdb"
|
||||
"shylinux.com/x/icebergs/base/mdb"
|
||||
"shylinux.com/x/icebergs/base/tcp"
|
||||
kit "shylinux.com/x/toolkits"
|
||||
"shylinux.com/x/toolkits/file"
|
||||
)
|
||||
|
||||
type Message interface {
|
||||
Option(key string, arg ...ice.Any) string
|
||||
PrefixKey(...string) string
|
||||
}
|
||||
|
||||
func UserWeb(m Message) *url.URL { return kit.ParseURL(m.Option(ice.MSG_USERWEB)) }
|
||||
func UserHost(m *ice.Message) string {
|
||||
if u := UserWeb(m); strings.Contains(u.Host, tcp.LOCALHOST) {
|
||||
return m.Option(ice.MSG_USERHOST, tcp.PublishLocalhost(m, u.Scheme+"://"+u.Host))
|
||||
} else {
|
||||
return m.Option(ice.MSG_USERHOST, u.Scheme+"://"+u.Host)
|
||||
}
|
||||
}
|
||||
func AgentIs(m Message, arg ...string) bool {
|
||||
for _, k := range arg {
|
||||
if strings.HasPrefix(strings.ToLower(m.Option(ice.MSG_USERUA)), k) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
func MergeURL2(m Message, url string, arg ...ice.Any) string {
|
||||
if m.Option(ice.MSG_USERWEB) == "" {
|
||||
return kit.MergeURL2(Domain(ice.Pulse.Cmdv(tcp.HOST, aaa.IP), ice.Pulse.Cmdv(SERVE, tcp.PORT)), url, arg...)
|
||||
}
|
||||
return kit.MergeURL2(m.Option(ice.MSG_USERWEB), url, arg...)
|
||||
}
|
||||
func MergeLink(m Message, url string, arg ...ice.Any) string {
|
||||
return kit.MergeURL(strings.Split(MergeURL2(m, url), ice.QS)[0], arg...)
|
||||
}
|
||||
func ProcessPodCmd(m *ice.Message, pod, cmd string, arg ...ice.Any) {
|
||||
m.ProcessOpen(m.MergePodCmd(pod, cmd, arg...))
|
||||
}
|
||||
func ProcessIframe(m *ice.Message, name, link string, arg ...string) {
|
||||
ctx.ProcessField(m, CHAT_IFRAME, func() []string {
|
||||
return []string{m.Cmdx(CHAT_IFRAME, mdb.CREATE, mdb.TYPE, LINK, mdb.NAME, name, LINK, link)}
|
||||
}, arg...)
|
||||
}
|
||||
func PushPodCmd(m *ice.Message, cmd string, arg ...string) {
|
||||
kit.If(m.Length() > 0 && len(m.Appendv(ice.POD)) == 0, func() { m.Table(func(value ice.Maps) { m.Push(ice.POD, m.Option(ice.MSG_USERPOD)) }) })
|
||||
m.Cmds(SPACE, func(value ice.Maps) {
|
||||
kit.Switch(value[mdb.TYPE], []string{SERVER, WORKER}, func() {
|
||||
m.Cmd(SPACE, value[mdb.NAME], kit.Select(m.PrefixKey(), cmd), arg).Table(func(index int, val ice.Maps, head []string) {
|
||||
val[ice.POD] = kit.Keys(value[mdb.NAME], val[ice.POD])
|
||||
m.Push("", val, head)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
func PushNotice(m *ice.Message, arg ...ice.Any) {
|
||||
if m.Option(ice.MSG_DAEMON) == "" {
|
||||
return
|
||||
}
|
||||
if m.Option(ice.MSG_USERPOD) == "" {
|
||||
msg := m.Spawn()
|
||||
msg.Optionv(ice.MSG_OPTS, msg.Optionv(ice.MSG_OPTION, []string{}))
|
||||
msg.Cmd(SPACE, m.Option(ice.MSG_DAEMON), arg)
|
||||
} else if m.Option(ice.MSG_USERPOD) == "" {
|
||||
m.Cmd(SPACE, m.Option(ice.MSG_DAEMON), arg, ice.Maps{ice.MSG_OPTION: "", ice.MSG_OPTS: ""})
|
||||
} else {
|
||||
m.Cmd(Prefix(SPIDE), ice.OPS, MergeURL2(m, SHARE_TOAST+m.Option(ice.MSG_DAEMON)), ice.ARG, kit.Format(arg))
|
||||
m.Cmd(Prefix(SPIDE), ice.OPS, MergeURL2(m, P(SHARE, TOAST, m.Option(ice.MSG_DAEMON))), ice.ARG, kit.Format(arg))
|
||||
}
|
||||
}
|
||||
func PushNoticeGrow(m *ice.Message, arg ...ice.Any) {
|
||||
PushNotice(m, kit.List("grow", arg)...)
|
||||
}
|
||||
func PushNoticeToast(m *ice.Message, arg ...ice.Any) {
|
||||
PushNotice(m, kit.List("toast", arg)...)
|
||||
}
|
||||
func PushNoticeRefresh(m *ice.Message, arg ...ice.Any) {
|
||||
PushNotice(m, kit.List("refresh")...)
|
||||
func PushNoticeGrow(m *ice.Message, arg ...ice.Any) { PushNotice(m, kit.List("grow", arg)...) }
|
||||
func PushNoticeToast(m *ice.Message, arg ...ice.Any) { PushNotice(m, kit.List("toast", arg)...) }
|
||||
func PushStream(m *ice.Message) *ice.Message {
|
||||
m.ProcessHold()
|
||||
return m.Options(cli.CMD_OUTPUT, file.NewWriteCloser(func(buf []byte) { PushNoticeGrow(m, string(buf)) }, func() { PushNoticeToast(m, "done") }))
|
||||
}
|
||||
|
||||
func ToastProcess(m *ice.Message, arg ...ice.Any) func() {
|
||||
if len(arg) == 0 {
|
||||
arg = kit.List("", "-1")
|
||||
}
|
||||
if len(arg) == 1 {
|
||||
arg = append(arg, "-1")
|
||||
}
|
||||
Toast(m, ice.PROCESS, arg...)
|
||||
return func() { Toast(m, ice.SUCCESS) }
|
||||
}
|
||||
func ToastRestart(m *ice.Message, arg ...ice.Any) { Toast(m, gdb.RESTART, arg...) }
|
||||
func ToastFailure(m *ice.Message, arg ...ice.Any) { Toast(m, ice.FAILURE, arg...) }
|
||||
func ToastSuccess(m *ice.Message, arg ...ice.Any) { Toast(m, ice.SUCCESS, arg...) }
|
||||
func Toast(m *ice.Message, text string, arg ...ice.Any) { // [title [duration [progress]]]
|
||||
if len(arg) > 1 {
|
||||
switch val := arg[1].(type) {
|
||||
@ -63,115 +91,20 @@ func Toast(m *ice.Message, text string, arg ...ice.Any) { // [title [duration [p
|
||||
}
|
||||
PushNoticeToast(m, text, arg)
|
||||
}
|
||||
func Toast3s(m *ice.Message, text string, arg ...ice.Any) *ice.Message {
|
||||
Toast(m, text, kit.List(kit.Select("", arg, 0), kit.Select("3s", arg, 1))...)
|
||||
return m
|
||||
}
|
||||
func Toast30s(m *ice.Message, text string, arg ...ice.Any) {
|
||||
Toast(m, text, kit.List(kit.Select("", arg, 0), kit.Select("30s", arg, 1))...)
|
||||
func ToastFailure(m *ice.Message, arg ...ice.Any) { Toast(m, ice.FAILURE, arg...) }
|
||||
func ToastSuccess(m *ice.Message, arg ...ice.Any) { Toast(m, ice.SUCCESS, arg...) }
|
||||
func ToastProcess(m *ice.Message, arg ...ice.Any) func() {
|
||||
kit.If(len(arg) == 0, func() { arg = kit.List("", "-1") })
|
||||
kit.If(len(arg) == 1, func() { arg = append(arg, "-1") })
|
||||
Toast(m, ice.PROCESS, arg...)
|
||||
return func() { Toast(m, ice.SUCCESS) }
|
||||
}
|
||||
func GoToast(m *ice.Message, title string, cb func(toast func(string, int, int))) {
|
||||
cb(func(name string, count, total int) {
|
||||
if total == 0 {
|
||||
total = 1
|
||||
}
|
||||
kit.If(total == 0, func() { total = 1 })
|
||||
Toast(m,
|
||||
kit.Format("%s %s/%s", name, strings.TrimSuffix(kit.FmtSize(int64(count)), "B"), strings.TrimSuffix(kit.FmtSize(int64(total)), "B")),
|
||||
kit.Format("%s %d%%", title, count*100/total),
|
||||
kit.Select("3000", "30000", count < total),
|
||||
count*100/total,
|
||||
kit.Format("%s %d%%", title, count*100/total), kit.Select("3000", "30000", count < total), count*100/total,
|
||||
)
|
||||
})
|
||||
}
|
||||
func PushStream(m *ice.Message, cmds ...ice.Any) *ice.Message {
|
||||
m.Option(cli.CMD_OUTPUT, file.NewWriteCloser(func(buf []byte) (int, error) {
|
||||
PushNoticeGrow(m, string(buf))
|
||||
return len(buf), nil
|
||||
}, func() error { PushNoticeToast(m, "done"); return nil }))
|
||||
m.ProcessHold()
|
||||
return m.Cmd(cmds...)
|
||||
}
|
||||
func PushPodCmd(m *ice.Message, cmd string, arg ...string) {
|
||||
if m.Length() > 0 && len(m.Appendv(ice.POD)) == 0 {
|
||||
m.Table(func(value ice.Maps) { m.Push(ice.POD, m.Option(ice.MSG_USERPOD)) })
|
||||
}
|
||||
|
||||
m.Cmd(SPACE, ice.OptionFields(mdb.TYPE, mdb.NAME), func(value ice.Maps) {
|
||||
switch value[mdb.TYPE] {
|
||||
case SERVER, WORKER:
|
||||
if value[mdb.NAME] == ice.Info.Hostname {
|
||||
break
|
||||
}
|
||||
m.Cmd(SPACE, value[mdb.NAME], kit.Select(m.PrefixKey(), cmd), arg).Table(func(index int, val ice.Maps, head []string) {
|
||||
val[ice.POD] = kit.Keys(value[mdb.NAME], val[ice.POD])
|
||||
m.Push("", val, head)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
type Message interface {
|
||||
Option(key string, arg ...ice.Any) string
|
||||
PrefixKey(...string) string
|
||||
}
|
||||
|
||||
func OptionAgentIs(m Message, arg ...string) bool {
|
||||
for _, k := range arg {
|
||||
if strings.HasPrefix(strings.ToLower(m.Option(ice.MSG_USERUA)), k) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
func OptionUserWeb(m Message) *url.URL {
|
||||
return kit.ParseURL(m.Option(ice.MSG_USERWEB))
|
||||
}
|
||||
func MergeURL2(m Message, url string, arg ...ice.Any) string {
|
||||
if m.Option(ice.MSG_USERWEB) == "" {
|
||||
return kit.MergeURL2(HTTP+"://"+ice.Pulse.Cmd(tcp.HOST).Append(aaa.IP)+":"+ice.Pulse.Cmd(SERVE).Append(tcp.PORT), url, arg...)
|
||||
}
|
||||
return kit.MergeURL2(m.Option(ice.MSG_USERWEB), url, arg...)
|
||||
}
|
||||
func MergeLink(m Message, url string, arg ...ice.Any) string {
|
||||
return strings.Split(MergeURL2(m, url, arg...), ice.QS)[0]
|
||||
}
|
||||
func MergePod(m Message, pod string, arg ...ice.Any) string {
|
||||
return kit.MergePOD(kit.Select(ice.Info.Domain, m.Option(ice.MSG_USERWEB)), pod, arg...)
|
||||
}
|
||||
func MergePods(m Message, pod string, arg ...ice.Any) string {
|
||||
return kit.MergeURL(strings.Split(MergePod(m, pod), ice.QS)[0], arg...)
|
||||
}
|
||||
func MergePodCmds(m Message, pod, cmd string, arg ...ice.Any) string {
|
||||
return kit.MergeURL(strings.Split(MergePodCmd(m, pod, cmd), ice.QS)[0], arg...)
|
||||
}
|
||||
func MergePodCmd(m Message, pod, cmd string, arg ...ice.Any) string {
|
||||
p := "/chat"
|
||||
p += path.Join("/pod/", kit.Keys(m.Option(ice.MSG_USERPOD), pod))
|
||||
p = kit.Select(p, "/chat", p == "/chat/pod")
|
||||
p += path.Join("/cmd/", kit.Select(m.PrefixKey(), cmd))
|
||||
return kit.MergeURL2(kit.Select(ice.Info.Domain, m.Option(ice.MSG_USERWEB)), p, arg...)
|
||||
}
|
||||
func MergePodWebSite(m Message, pod, web string, arg ...ice.Any) string {
|
||||
p := "/chat"
|
||||
p += "/pod/" + kit.Keys(m.Option(ice.MSG_USERPOD), pod)
|
||||
p = kit.Select(p, "/chat/", p == "/chat/pod/")
|
||||
p += "/website/" + kit.Select("index.iml", web)
|
||||
return kit.MergeURL2(kit.Select(ice.Info.Domain, m.Option(ice.MSG_USERWEB)), p, arg...)
|
||||
}
|
||||
func ProcessWebsite(m *ice.Message, pod, cmd string, arg ...ice.Any) {
|
||||
m.ProcessOpen(MergePodCmd(m, pod, cmd, arg...))
|
||||
}
|
||||
func ProcessIframe(m *ice.Message, name, link string, arg ...string) {
|
||||
if len(arg) == 0 || arg[0] != ice.RUN {
|
||||
arg = []string{m.Cmdx("web.chat.iframe", mdb.CREATE, mdb.TYPE, LINK, mdb.NAME, name, LINK, link)}
|
||||
}
|
||||
ctx.ProcessField(m, "web.chat.iframe", arg, arg...)
|
||||
}
|
||||
|
||||
func UserHost(m *ice.Message) string {
|
||||
if u := OptionUserWeb(m); strings.Contains(u.Host, tcp.LOCALHOST) {
|
||||
return m.Option(ice.MSG_USERHOST, tcp.PublishLocalhost(m, u.Scheme+"://"+u.Host))
|
||||
} else {
|
||||
return m.Option(ice.MSG_USERHOST, u.Scheme+"://"+u.Host)
|
||||
}
|
||||
}
|
||||
|
@ -141,7 +141,8 @@ func renderVersion(m *ice.Message) string {
|
||||
}
|
||||
|
||||
const (
|
||||
WEBSITE = "website"
|
||||
BLACK = "black"
|
||||
DISPLAY = "display"
|
||||
RESIZE = "resize"
|
||||
LAYOUT = "layout"
|
||||
OUTPUT = "output"
|
||||
@ -149,9 +150,10 @@ const (
|
||||
VIEW = "view"
|
||||
CHAT = "chat"
|
||||
|
||||
CODE_VIMER = "web.code.vimer"
|
||||
CODE_INNER = "web.code.inner"
|
||||
CODE_XTERM = "web.code.xterm"
|
||||
CHAT_FAVOR = "web.chat.favor"
|
||||
WIKI_WORD = "web.wiki.word"
|
||||
CODE_VIMER = "web.code.vimer"
|
||||
CODE_INNER = "web.code.inner"
|
||||
CODE_XTERM = "web.code.xterm"
|
||||
CHAT_FAVOR = "web.chat.favor"
|
||||
CHAT_IFRAME = "web.chat.iframe"
|
||||
WIKI_WORD = "web.wiki.word"
|
||||
)
|
||||
|
@ -143,10 +143,12 @@ const (
|
||||
HTTP = "http"
|
||||
HTTPS = "https"
|
||||
DOMAIN = "domain"
|
||||
ORIGIN = "origin"
|
||||
FORM = "form"
|
||||
BODY = "body"
|
||||
|
||||
ApplicationJSON = "Application/json"
|
||||
ApplicationJSON = "Application/json"
|
||||
ApplicationOctet = "application/octet-stream"
|
||||
)
|
||||
const SERVE = "serve"
|
||||
|
||||
@ -182,3 +184,9 @@ func init() {
|
||||
}
|
||||
})
|
||||
}
|
||||
func Domain(host, port string) string {
|
||||
return kit.Format("%s://%s:%s", HTTP, host, port)
|
||||
}
|
||||
func Script(m *ice.Message, str string, arg ...ice.Any) string {
|
||||
return ice.Render(m, ice.RENDER_SCRIPT, kit.Format(str, arg...))
|
||||
}
|
||||
|
@ -18,16 +18,15 @@ import (
|
||||
"shylinux.com/x/toolkits/logs"
|
||||
)
|
||||
|
||||
func _share_link(m *ice.Message, p string) string {
|
||||
return tcp.PublishLocalhost(m, MergeLink(m, kit.Select("", SHARE_LOCAL, !strings.HasPrefix(p, ice.PS) && !strings.HasPrefix(p, HTTP))+p))
|
||||
func _share_link(m *ice.Message, p string, arg ...ice.Any) string {
|
||||
return tcp.PublishLocalhost(m, MergeLink(m, kit.Select("", PP(SHARE, LOCAL), !strings.HasPrefix(p, ice.PS) && !strings.HasPrefix(p, HTTP))+p, arg...))
|
||||
}
|
||||
func _share_cache(m *ice.Message, arg ...string) {
|
||||
if pod := m.Option(ice.POD); ctx.PodCmd(m, CACHE, arg[0]) {
|
||||
if m.Append(nfs.FILE) == "" {
|
||||
m.RenderResult(m.Append(mdb.TEXT))
|
||||
} else {
|
||||
m.Option(ice.POD, pod)
|
||||
ShareLocalFile(m, m.Append(nfs.FILE))
|
||||
ShareLocalFile(m.Options(ice.POD, pod), m.Append(nfs.FILE))
|
||||
}
|
||||
} else {
|
||||
if m.Cmdy(CACHE, arg[0]); m.Append(nfs.FILE) == "" {
|
||||
@ -50,19 +49,16 @@ func _share_proxy(m *ice.Message) {
|
||||
}
|
||||
|
||||
const (
|
||||
THEME = "theme"
|
||||
LOGIN = "login"
|
||||
RIVER = "river"
|
||||
STORM = "storm"
|
||||
FIELD = "field"
|
||||
|
||||
SHARE_CACHE = "/share/cache/"
|
||||
SHARE_LOCAL = "/share/local/"
|
||||
SHARE_PROXY = "/share/proxy/"
|
||||
SHARE_TOAST = "/share/toast/"
|
||||
LOCAL = "local"
|
||||
PROXY = "proxy"
|
||||
TOAST = "toast"
|
||||
|
||||
SHARE_LOCAL_AVATAR = "/share/local/avatar/"
|
||||
SHARE_LOCAL_BACKGROUND = "/share/local/background/"
|
||||
SHARE_LOCAL = "/share/local/"
|
||||
)
|
||||
const SHARE = "share"
|
||||
|
||||
@ -82,8 +78,7 @@ func init() {
|
||||
}
|
||||
msg := m.Cmd(SHARE, m.Option(SHARE, arg[0]))
|
||||
if IsNotValidShare(m, msg.Append(mdb.TIME)) {
|
||||
m.RenderResult(kit.Format("共享超时, 请联系 %s(%s), 重新分享 %s %s",
|
||||
msg.Append(aaa.USERNICK), msg.Append(aaa.USERNAME), msg.Append(mdb.TYPE), msg.Append(mdb.NAME)))
|
||||
m.RenderResult(kit.Format("共享超时, 请联系 %s(%s), 重新分享 %s %s", msg.Append(aaa.USERNICK), msg.Append(aaa.USERNAME), msg.Append(mdb.TYPE), msg.Append(mdb.NAME)))
|
||||
return
|
||||
}
|
||||
switch msg.Append(mdb.TYPE) {
|
||||
@ -104,16 +99,16 @@ func init() {
|
||||
m.PushAnchor(link)
|
||||
}
|
||||
}},
|
||||
SHARE_CACHE: {Hand: func(m *ice.Message, arg ...string) { _share_cache(m, arg...) }},
|
||||
SHARE_LOCAL: {Hand: func(m *ice.Message, arg ...string) { ShareLocalFile(m, arg...) }},
|
||||
SHARE_LOCAL_AVATAR: {Hand: func(m *ice.Message, arg ...string) {
|
||||
m.RenderDownload(strings.TrimPrefix(m.Cmdv(aaa.USER, m.Option(ice.MSG_USERNAME), aaa.AVATAR), SHARE_LOCAL))
|
||||
PP(SHARE, CACHE): {Hand: func(m *ice.Message, arg ...string) { _share_cache(m, arg...) }},
|
||||
PP(SHARE, LOCAL): {Hand: func(m *ice.Message, arg ...string) { ShareLocalFile(m, arg...) }},
|
||||
PP(SHARE, LOCAL, aaa.AVATAR): {Hand: func(m *ice.Message, arg ...string) {
|
||||
m.RenderDownload(strings.TrimPrefix(m.Cmdv(aaa.USER, m.Option(ice.MSG_USERNAME), aaa.AVATAR), PP(SHARE, LOCAL)))
|
||||
}},
|
||||
SHARE_LOCAL_BACKGROUND: {Hand: func(m *ice.Message, arg ...string) {
|
||||
m.RenderDownload(strings.TrimPrefix(m.Cmdv(aaa.USER, m.Option(ice.MSG_USERNAME), aaa.BACKGROUND), SHARE_LOCAL))
|
||||
PP(SHARE, LOCAL, aaa.BACKGROUND): {Hand: func(m *ice.Message, arg ...string) {
|
||||
m.RenderDownload(strings.TrimPrefix(m.Cmdv(aaa.USER, m.Option(ice.MSG_USERNAME), aaa.BACKGROUND), PP(SHARE, LOCAL)))
|
||||
}},
|
||||
SHARE_PROXY: {Hand: func(m *ice.Message, arg ...string) { _share_proxy(m) }},
|
||||
SHARE_TOAST: {Hand: func(m *ice.Message, arg ...string) { m.Cmdy(SPACE, arg[0], kit.UnMarshal(m.Option(ice.ARG))) }},
|
||||
PP(SHARE, PROXY): {Hand: func(m *ice.Message, arg ...string) { _share_proxy(m) }},
|
||||
PP(SHARE, TOAST): {Hand: func(m *ice.Message, arg ...string) { m.Cmdy(SPACE, arg[0], kit.UnMarshal(m.Option(ice.ARG))) }},
|
||||
})
|
||||
}
|
||||
func IsNotValidShare(m *ice.Message, time string) bool {
|
||||
@ -141,7 +136,6 @@ func ShareLocalFile(m *ice.Message, arg ...string) {
|
||||
cache, size = s.ModTime(), s.Size()
|
||||
}
|
||||
kit.If(p == ice.BIN_ICE_BIN, func() { m.Option(ice.MSG_USERROLE, aaa.TECH) })
|
||||
m.Cmd(SPACE, m.Option(ice.POD), SPIDE, ice.DEV, SPIDE_RAW, MergeLink(m, SHARE_PROXY),
|
||||
SPIDE_PART, m.OptionSimple(ice.POD), nfs.PATH, p, nfs.SIZE, size, CACHE, cache.Format(ice.MOD_TIME), UPLOAD, ice.AT+p)
|
||||
m.Cmd(SPACE, m.Option(ice.POD), SPIDE, ice.DEV, SPIDE_RAW, MergeLink(m, PP(SHARE, PROXY)), SPIDE_PART, m.OptionSimple(ice.POD), nfs.PATH, p, nfs.SIZE, size, CACHE, cache.Format(ice.MOD_TIME), UPLOAD, ice.AT+p)
|
||||
m.RenderDownload(kit.Select(p, pp, file.ExistsFile(pp)))
|
||||
}
|
||||
|
@ -16,16 +16,16 @@ import (
|
||||
"shylinux.com/x/icebergs/base/mdb"
|
||||
"shylinux.com/x/icebergs/base/ssh"
|
||||
"shylinux.com/x/icebergs/base/tcp"
|
||||
"shylinux.com/x/icebergs/misc/websocket"
|
||||
kit "shylinux.com/x/toolkits"
|
||||
"shylinux.com/x/websocket"
|
||||
)
|
||||
|
||||
func _space_qrcode(m *ice.Message, dev string) {
|
||||
ssh.PrintQRCode(m, m.Cmdv(SPACE, dev, cli.PWD, mdb.LINK))
|
||||
}
|
||||
func _space_dial(m *ice.Message, dev, name string, arg ...string) {
|
||||
uri := kit.ParseURL(kit.MergeURL2(strings.Replace(m.Cmdv(SPIDE, dev, CLIENT_ORIGIN), HTTP, "ws", 1), PP(SPACE), mdb.TYPE, ice.Info.NodeType, mdb.NAME, name, arg))
|
||||
args := kit.SimpleKV("type,name,host,port", uri.Scheme, dev, uri.Hostname(), uri.Port())
|
||||
u := kit.ParseURL(kit.MergeURL2(strings.Replace(m.Cmdv(SPIDE, dev, CLIENT_ORIGIN), HTTP, "ws", 1), PP(SPACE), mdb.TYPE, ice.Info.NodeType, mdb.NAME, name, arg))
|
||||
args := kit.SimpleKV("type,name,host,port", u.Scheme, dev, u.Hostname(), u.Port())
|
||||
m.Go(func() {
|
||||
once := sync.Once{}
|
||||
redial := kit.Dict(mdb.Configv(m, REDIAL))
|
||||
@ -33,13 +33,13 @@ func _space_dial(m *ice.Message, dev, name string, arg ...string) {
|
||||
for i := 1; i < c; i++ {
|
||||
next := time.Duration(rand.Intn(a*(i+1))+b*i) * time.Millisecond
|
||||
m.Cmd(tcp.CLIENT, tcp.DIAL, args, func(c net.Conn) {
|
||||
if c, _, e := websocket.NewClient(c, uri, nil, ice.MOD_BUFS, ice.MOD_BUFS); !m.Warn(e, tcp.DIAL, dev, SPACE, uri.String()) {
|
||||
defer mdb.HashCreateDeferRemove(m, kit.SimpleKV("", MASTER, dev, uri.Hostname()), kit.Dict(mdb.TARGET, c))()
|
||||
if c, e := websocket.NewClient(c, u); !m.Warn(e, tcp.DIAL, dev, SPACE, u.String()) {
|
||||
defer mdb.HashCreateDeferRemove(m, kit.SimpleKV("", MASTER, dev, u.Hostname()), kit.Dict(mdb.TARGET, c))()
|
||||
kit.If(ice.Info.Colors, func() { once.Do(func() { m.Go(func() { _space_qrcode(m, dev) }) }) })
|
||||
_space_handle(m.Spawn(), true, dev, c)
|
||||
i = 0
|
||||
}
|
||||
}).Cost(mdb.COUNT, i, mdb.NEXT, next, tcp.DIAL, dev, LINK, uri.String()).Sleep(next)
|
||||
}).Cost(mdb.COUNT, i, mdb.NEXT, next, tcp.DIAL, dev, LINK, u.String()).Sleep(next)
|
||||
}
|
||||
}, kit.Join(kit.Simple(SPACE, name), ice.SP))
|
||||
}
|
||||
@ -47,7 +47,7 @@ func _space_fork(m *ice.Message) {
|
||||
addr := kit.Select(m.R.RemoteAddr, m.R.Header.Get(ice.MSG_USERADDR))
|
||||
name := kit.ReplaceAll(kit.Select(addr, m.Option(mdb.NAME)), "[", "_", "]", "_", ice.DF, "_", ice.PT, "_")
|
||||
args := kit.Simple(mdb.TYPE, kit.Select(WORKER, m.Option(mdb.TYPE)), mdb.NAME, name, mdb.TEXT, kit.Select(addr, m.Option(mdb.TEXT)), m.OptionSimple(cli.DAEMON, ice.MSG_USERUA))
|
||||
if c, e := websocket.Upgrade(m.W, m.R, nil, ice.MOD_BUFS, ice.MOD_BUFS); !m.Warn(e) {
|
||||
if c, e := websocket.Upgrade(m.W, m.R); !m.Warn(e) {
|
||||
m.Go(func() {
|
||||
defer mdb.HashCreateDeferRemove(m, args, kit.Dict(mdb.TARGET, c))()
|
||||
switch m.Option(mdb.TYPE) {
|
||||
@ -164,6 +164,7 @@ func init() {
|
||||
}
|
||||
_space_dial(m, m.Option(ice.DEV), kit.Select(ice.Info.NodeName, m.Option(mdb.NAME)), arg...)
|
||||
}},
|
||||
cli.START: {Hand: func(m *ice.Message, arg ...string) { m.Cmdy("", tcp.DIAL, arg) }},
|
||||
mdb.REMOVE: {Hand: func(m *ice.Message, arg ...string) {
|
||||
defer mdb.HashModifyDeferRemove(m, m.OptionSimple(mdb.NAME), mdb.STATUS, cli.STOP)()
|
||||
m.Cmd("", m.Option(mdb.NAME), ice.EXIT)
|
||||
@ -175,7 +176,7 @@ func init() {
|
||||
case MASTER:
|
||||
m.PushSearch(mdb.TEXT, m.Cmdv(SPIDE, value[mdb.NAME], CLIENT_ORIGIN), value)
|
||||
case SERVER:
|
||||
m.PushSearch(mdb.TEXT, MergePods(m, value[mdb.NAME]), value)
|
||||
m.PushSearch(mdb.TEXT, m.MergePod(value[mdb.NAME]), value)
|
||||
}
|
||||
})
|
||||
} else if arg[0] == mdb.FOREACH && arg[1] == ssh.SHELL {
|
||||
@ -192,13 +193,11 @@ func init() {
|
||||
case MASTER:
|
||||
ctx.ProcessOpen(m, m.Cmdv(SPIDE, m.Option(mdb.NAME), CLIENT_ORIGIN))
|
||||
default:
|
||||
ctx.ProcessOpen(m, MergePods(m, m.Option(mdb.NAME), arg))
|
||||
ctx.ProcessOpen(m, m.MergePod(m.Option(mdb.NAME), arg))
|
||||
}
|
||||
}},
|
||||
ice.PS: {Hand: func(m *ice.Message, arg ...string) { _space_fork(m) }},
|
||||
}, mdb.HashAction(mdb.SHORT, mdb.NAME, mdb.FIELD, "time,type,name,text", ctx.ACTION, OPEN,
|
||||
REDIAL, kit.Dict("a", 3000, "b", 1000, "c", 1000),
|
||||
), mdb.ClearOnExitHashAction()), Hand: func(m *ice.Message, arg ...string) {
|
||||
}, mdb.HashAction(mdb.SHORT, mdb.NAME, mdb.FIELD, "time,type,name,text", ctx.ACTION, OPEN, REDIAL, kit.Dict("a", 3000, "b", 1000, "c", 1000)), mdb.ClearOnExitHashAction()), Hand: func(m *ice.Message, arg ...string) {
|
||||
if len(arg) < 2 {
|
||||
mdb.HashSelect(m, arg...).Sort("").Table(func(value ice.Maps) { m.PushButton(kit.Select(OPEN, LOGIN, value[mdb.TYPE] == LOGIN), mdb.REMOVE) })
|
||||
} else {
|
||||
|
@ -20,37 +20,24 @@ import (
|
||||
kit "shylinux.com/x/toolkits"
|
||||
)
|
||||
|
||||
func _spide_create(m *ice.Message, name, address string) {
|
||||
if uri, e := url.Parse(address); !m.Warn(e != nil || address == "", ice.ErrNotValid, address) {
|
||||
m.Logs(mdb.INSERT, SPIDE, name, ADDRESS, address)
|
||||
func _spide_create(m *ice.Message, name, link string) {
|
||||
if u, e := url.Parse(link); !m.Warn(e != nil || link == "", ice.ErrNotValid, link) {
|
||||
dir, file := path.Split(u.EscapedPath())
|
||||
m.Logs(mdb.INSERT, SPIDE, name, LINK, link)
|
||||
mdb.HashSelectUpdate(m, mdb.HashCreate(m, CLIENT_NAME, name), func(value ice.Map) {
|
||||
dir, file := path.Split(uri.EscapedPath())
|
||||
value[SPIDE_CLIENT] = kit.Dict(mdb.NAME, name, SPIDE_METHOD, http.MethodPost, "url", address, "origin", uri.Scheme+"://"+uri.Host,
|
||||
tcp.PROTOCOL, uri.Scheme, tcp.HOSTNAME, uri.Hostname(), tcp.HOST, uri.Host, nfs.PATH, dir, nfs.FILE, file, "query", uri.RawQuery,
|
||||
cli.TIMEOUT, "300ms", LOGHEADERS, ice.FALSE,
|
||||
value[SPIDE_CLIENT] = kit.Dict(mdb.NAME, name, SPIDE_METHOD, http.MethodPost, "url", link, ORIGIN, u.Scheme+"://"+u.Host,
|
||||
tcp.PROTOCOL, u.Scheme, tcp.HOSTNAME, u.Hostname(), tcp.HOST, u.Host, nfs.PATH, dir, nfs.FILE, file, cli.TIMEOUT, "3s",
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
func _spide_args(m *ice.Message, arg []string, val ...string) (string, []string) {
|
||||
if kit.IndexOf(val, arg[0]) > -1 {
|
||||
return arg[0], arg[1:]
|
||||
}
|
||||
return "", arg
|
||||
}
|
||||
func _spide_show(m *ice.Message, name string, arg ...string) {
|
||||
msg := mdb.HashSelects(m.Spawn(), name)
|
||||
if len(arg) == 1 && msg.Append(arg[0]) != "" {
|
||||
m.Echo(msg.Append(arg[0]))
|
||||
return
|
||||
}
|
||||
format, arg := _spide_args(m, arg, SPIDE_RAW, SPIDE_MSG, SPIDE_CACHE, SPIDE_SAVE)
|
||||
file := ""
|
||||
if format == SPIDE_SAVE {
|
||||
file, arg = arg[0], arg[1:]
|
||||
}
|
||||
action, arg := _spide_args(m, arg, SPIDE_RAW, SPIDE_MSG, SPIDE_CACHE, SPIDE_SAVE)
|
||||
kit.If(action == SPIDE_SAVE, func() { file, arg = arg[0], arg[1:] })
|
||||
msg := mdb.HashSelects(m.Spawn(), name)
|
||||
method, arg := _spide_args(m, arg, http.MethodGet, http.MethodPut, http.MethodPost, http.MethodDelete)
|
||||
method = kit.Select(http.MethodPost, kit.Select(msg.Append(CLIENT_METHOD), method))
|
||||
method = kit.Select(http.MethodPost, msg.Append(CLIENT_METHOD), method)
|
||||
uri, arg := arg[0], arg[1:]
|
||||
body, head, arg := _spide_body(m, method, arg...)
|
||||
if c, ok := body.(io.Closer); ok {
|
||||
@ -66,17 +53,13 @@ func _spide_show(m *ice.Message, name string, arg ...string) {
|
||||
return
|
||||
}
|
||||
defer res.Body.Close()
|
||||
if mdb.Config(m, LOGHEADERS) == ice.TRUE {
|
||||
for k, v := range res.Header {
|
||||
m.Logs(mdb.IMPORT, k, v)
|
||||
}
|
||||
}
|
||||
m.Cost(cli.STATUS, res.Status, nfs.SIZE, res.Header.Get(ContentLength), mdb.TYPE, res.Header.Get(ContentType))
|
||||
kit.For(res.Header, func(k string, v []string) { m.Logs(mdb.IMPORT, k, v) })
|
||||
mdb.HashSelectUpdate(m, name, func(value ice.Map) {
|
||||
for _, v := range res.Cookies() {
|
||||
kit.For(res.Cookies(), func(v *http.Cookie) {
|
||||
kit.Value(value, kit.Keys(SPIDE_COOKIE, v.Name), v.Value)
|
||||
m.Logs(mdb.IMPORT, v.Name, v.Value)
|
||||
}
|
||||
})
|
||||
})
|
||||
if m.Warn(res.StatusCode != http.StatusOK, ice.ErrNotValid, uri, cli.STATUS, res.Status) {
|
||||
switch res.StatusCode {
|
||||
@ -84,41 +67,42 @@ func _spide_show(m *ice.Message, name string, arg ...string) {
|
||||
return
|
||||
}
|
||||
}
|
||||
_spide_save(m, format, file, uri, res)
|
||||
_spide_save(m, action, file, uri, res)
|
||||
}
|
||||
func _spide_args(m *ice.Message, arg []string, val ...string) (string, []string) {
|
||||
if kit.IndexOf(val, arg[0]) > -1 {
|
||||
return arg[0], arg[1:]
|
||||
}
|
||||
return "", arg
|
||||
}
|
||||
func _spide_body(m *ice.Message, method string, arg ...string) (io.Reader, ice.Maps, []string) {
|
||||
head := ice.Maps{}
|
||||
body, ok := m.Optionv(SPIDE_BODY).(io.Reader)
|
||||
if !ok && len(arg) > 0 && method != http.MethodGet {
|
||||
if len(arg) == 1 {
|
||||
arg = []string{SPIDE_DATA, arg[0]}
|
||||
}
|
||||
switch arg[0] {
|
||||
case SPIDE_FORM:
|
||||
arg = kit.Simple(arg, func(v string) string { return url.QueryEscape(v) })
|
||||
head[ContentType], body = ContentFORM, bytes.NewBufferString(kit.JoinKV("=", "&", arg[1:]...))
|
||||
case SPIDE_PART:
|
||||
head[ContentType], body = _spide_part(m, arg...)
|
||||
case SPIDE_DATA:
|
||||
head[ContentType], body = ContentJSON, bytes.NewBufferString(kit.Select("{}", arg, 1))
|
||||
case SPIDE_FILE:
|
||||
if f, e := nfs.OpenFile(m, arg[1]); m.Assert(e) {
|
||||
m.Logs(mdb.IMPORT, nfs.FILE, arg[1])
|
||||
body = f
|
||||
}
|
||||
case SPIDE_JSON:
|
||||
arg = arg[1:]
|
||||
fallthrough
|
||||
default:
|
||||
data := ice.Map{}
|
||||
kit.For(arg, func(k, v string) { kit.Value(data, k, v) })
|
||||
head[ContentType], body = ContentJSON, bytes.NewBufferString(kit.Format(data))
|
||||
}
|
||||
arg = arg[:0]
|
||||
} else {
|
||||
body = bytes.NewBuffer([]byte{})
|
||||
if ok || method == http.MethodGet || len(arg) == 0 {
|
||||
return body, nil, arg
|
||||
}
|
||||
return body, head, arg
|
||||
head := ice.Maps{}
|
||||
switch kit.If(len(arg) == 1, func() { arg = []string{SPIDE_DATA, arg[0]} }); arg[0] {
|
||||
case SPIDE_FORM:
|
||||
arg = kit.Simple(arg, func(v string) string { return url.QueryEscape(v) })
|
||||
head[ContentType], body = ContentFORM, bytes.NewBufferString(kit.JoinKV("=", "&", arg[1:]...))
|
||||
case SPIDE_PART:
|
||||
head[ContentType], body = _spide_part(m, arg...)
|
||||
case SPIDE_FILE:
|
||||
if f, e := nfs.OpenFile(m, arg[1]); m.Assert(e) {
|
||||
m.Logs(nfs.LOAD, nfs.FILE, arg[1])
|
||||
body = f
|
||||
}
|
||||
case SPIDE_DATA:
|
||||
head[ContentType], body = ApplicationJSON, bytes.NewBufferString(kit.Select("{}", arg, 1))
|
||||
case SPIDE_JSON:
|
||||
arg = arg[1:]
|
||||
fallthrough
|
||||
default:
|
||||
data := ice.Map{}
|
||||
kit.For(arg, func(k, v string) { kit.Value(data, k, v) })
|
||||
head[ContentType], body = ApplicationJSON, bytes.NewBufferString(kit.Format(data))
|
||||
}
|
||||
return body, head, arg[:0]
|
||||
}
|
||||
func _spide_part(m *ice.Message, arg ...string) (string, io.Reader) {
|
||||
buf := &bytes.Buffer{}
|
||||
@ -137,13 +121,13 @@ func _spide_part(m *ice.Message, arg ...string) (string, io.Reader) {
|
||||
if s.Size() == size && s.ModTime().Before(cache) {
|
||||
continue
|
||||
}
|
||||
m.Logs(mdb.IMPORT, "local", s.ModTime(), nfs.SIZE, s.Size(), CACHE, cache, nfs.SIZE, size)
|
||||
m.Logs(nfs.FIND, LOCAL, s.ModTime(), nfs.SIZE, s.Size(), CACHE, cache, nfs.SIZE, size)
|
||||
}
|
||||
if f, e := nfs.OpenFile(m, arg[i+1][1:]); !m.Warn(e, ice.ErrNotValid, arg[i+1]) {
|
||||
defer f.Close()
|
||||
if p, e := mp.CreateFormFile(arg[i], path.Base(arg[i+1][1:])); !m.Warn(e, ice.ErrNotValid, arg[i+1]) {
|
||||
if n, e := io.Copy(p, f); !m.Warn(e, ice.ErrNotValid, arg[i+1]) {
|
||||
m.Logs(mdb.EXPORT, nfs.FILE, arg[i+1], nfs.SIZE, n)
|
||||
m.Logs(nfs.LOAD, nfs.FILE, arg[i+1], nfs.SIZE, n)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -155,10 +139,6 @@ func _spide_part(m *ice.Message, arg ...string) (string, io.Reader) {
|
||||
}
|
||||
func _spide_head(m *ice.Message, req *http.Request, head ice.Maps, value ice.Map) {
|
||||
m.Logs(req.Method, req.URL.String())
|
||||
kit.For(value[SPIDE_HEADER], func(k string, v string) {
|
||||
req.Header.Set(k, v)
|
||||
m.Logs("Header", k, v)
|
||||
})
|
||||
kit.For(value[SPIDE_COOKIE], func(k string, v string) {
|
||||
req.AddCookie(&http.Cookie{Name: k, Value: v})
|
||||
m.Logs("Cookie", k, v)
|
||||
@ -167,6 +147,10 @@ func _spide_head(m *ice.Message, req *http.Request, head ice.Maps, value ice.Map
|
||||
req.AddCookie(&http.Cookie{Name: k, Value: v})
|
||||
m.Logs("Cookie", k, v)
|
||||
})
|
||||
kit.For(value[SPIDE_HEADER], func(k string, v string) {
|
||||
req.Header.Set(k, v)
|
||||
m.Logs("Header", k, v)
|
||||
})
|
||||
kit.For(kit.Simple(m.Optionv(SPIDE_HEADER)), func(k, v string) {
|
||||
req.Header.Set(k, v)
|
||||
m.Logs("Header", k, v)
|
||||
@ -175,18 +159,16 @@ func _spide_head(m *ice.Message, req *http.Request, head ice.Maps, value ice.Map
|
||||
req.Header.Set(k, v)
|
||||
m.Logs("Header", k, v)
|
||||
})
|
||||
if req.Method == http.MethodPost {
|
||||
m.Logs(kit.Select(ice.AUTO, req.Header.Get(ContentLength)), req.Header.Get(ContentType))
|
||||
}
|
||||
kit.If(req.Method == http.MethodPost, func() { m.Logs(kit.Select(ice.AUTO, req.Header.Get(ContentLength)), req.Header.Get(ContentType)) })
|
||||
}
|
||||
func _spide_send(m *ice.Message, name string, req *http.Request, timeout string) (*http.Response, error) {
|
||||
client := mdb.HashSelectTarget(m, name, func() ice.Any { return &http.Client{Timeout: kit.Duration(timeout)} }).(*http.Client)
|
||||
return client.Do(req)
|
||||
}
|
||||
func _spide_save(m *ice.Message, format, file, uri string, res *http.Response) {
|
||||
switch format {
|
||||
func _spide_save(m *ice.Message, action, file, uri string, res *http.Response) {
|
||||
switch action {
|
||||
case SPIDE_RAW:
|
||||
if b, _ := ioutil.ReadAll(res.Body); strings.HasPrefix(res.Header.Get(ContentType), ContentJSON) {
|
||||
if b, _ := ioutil.ReadAll(res.Body); strings.HasPrefix(res.Header.Get(ContentType), ApplicationJSON) {
|
||||
m.Echo(kit.Formats(kit.UnMarshal(string(b))))
|
||||
} else {
|
||||
m.Echo(string(b))
|
||||
@ -222,9 +204,9 @@ const (
|
||||
SPIDE_BODY = "body"
|
||||
SPIDE_FORM = "form"
|
||||
SPIDE_PART = "part"
|
||||
SPIDE_JSON = "json"
|
||||
SPIDE_DATA = "data"
|
||||
SPIDE_FILE = "file"
|
||||
SPIDE_DATA = "data"
|
||||
SPIDE_JSON = "json"
|
||||
SPIDE_RES = "content_data"
|
||||
|
||||
Bearer = "Bearer"
|
||||
@ -236,7 +218,6 @@ const (
|
||||
Accept = "Accept"
|
||||
|
||||
ContentFORM = "application/x-www-form-urlencoded"
|
||||
ContentJSON = "application/json"
|
||||
ContentPNG = "image/png"
|
||||
ContentHTML = "text/html"
|
||||
ContentCSS = "text/css"
|
||||
@ -244,26 +225,23 @@ const (
|
||||
const (
|
||||
SPIDE_CLIENT = "client"
|
||||
SPIDE_METHOD = "method"
|
||||
SPIDE_HEADER = "header"
|
||||
SPIDE_COOKIE = "cookie"
|
||||
SPIDE_HEADER = "header"
|
||||
|
||||
CLIENT_NAME = "client.name"
|
||||
CLIENT_METHOD = "client.method"
|
||||
CLIENT_TIMEOUT = "client.timeout"
|
||||
CLIENT_PROTOCOL = "client.protocol"
|
||||
CLIENT_HOSTNAME = "client.hostname"
|
||||
CLIENT_TIMEOUT = "client.timeout"
|
||||
CLIENT_ORIGIN = "client.origin"
|
||||
CLIENT_URL = "client.url"
|
||||
|
||||
CLIENT_NAME = "client.name"
|
||||
CLIENT_METHOD = "client.method"
|
||||
CLIENT_ORIGIN = "client.origin"
|
||||
CLIENT_URL = "client.url"
|
||||
|
||||
OPEN = "open"
|
||||
FULL = "full"
|
||||
LINK = "link"
|
||||
MERGE = "merge"
|
||||
ADDRESS = "address"
|
||||
REQUEST = "request"
|
||||
RESPONSE = "response"
|
||||
LOGHEADERS = "logheaders"
|
||||
OPEN = "open"
|
||||
FULL = "full"
|
||||
LINK = "link"
|
||||
MERGE = "merge"
|
||||
REQUEST = "request"
|
||||
RESPONSE = "response"
|
||||
)
|
||||
const SPIDE = "spide"
|
||||
|
||||
@ -277,24 +255,17 @@ func init() {
|
||||
m.Cmd("", mdb.CREATE, ice.COM, kit.Select("https://contexts.com.cn", conf[cli.CTX_COM]))
|
||||
m.Cmd("", mdb.CREATE, ice.SHY, kit.Select(kit.Select("https://shylinux.com", ice.Info.Make.Remote), conf[cli.CTX_SHY]))
|
||||
}},
|
||||
mdb.CREATE: {Name: "create name address", Hand: func(m *ice.Message, arg ...string) { _spide_create(m, m.Option(mdb.NAME), m.Option(ADDRESS)) }},
|
||||
mdb.SEARCH: {Hand: func(m *ice.Message, arg ...string) {
|
||||
if arg[0] == mdb.FOREACH && arg[1] == "" {
|
||||
m.PushSearch(mdb.TYPE, LINK, mdb.NAME, ice.DEV, mdb.TEXT, mdb.HashSelectField(m, ice.COM, CLIENT_ORIGIN))
|
||||
m.PushSearch(mdb.TYPE, LINK, mdb.NAME, ice.SHY, mdb.TEXT, mdb.HashSelectField(m, ice.SHY, CLIENT_ORIGIN))
|
||||
}
|
||||
}},
|
||||
tcp.CLIENT: {Hand: func(m *ice.Message, arg ...string) {
|
||||
msg := m.Cmd("", kit.Select(ice.DEV, arg, 0))
|
||||
ls := kit.Split(msg.Append(kit.Keys(SPIDE_CLIENT, tcp.HOST)), ice.DF)
|
||||
m.Push(tcp.HOST, ls[0]).Push(tcp.PORT, kit.Select(kit.Select("443", "80", msg.Append(CLIENT_PROTOCOL) == HTTP), ls, 1))
|
||||
m.Push(DOMAIN, msg.Append(CLIENT_PROTOCOL)+"://"+msg.Append(CLIENT_HOSTNAME)+kit.Select("", arg, 1))
|
||||
m.Push(tcp.PROTOCOL, msg.Append(CLIENT_PROTOCOL)).Push(tcp.HOSTNAME, msg.Append(CLIENT_HOSTNAME))
|
||||
}},
|
||||
mdb.CREATE: {Name: "create name link", Hand: func(m *ice.Message, arg ...string) { _spide_create(m, m.Option(mdb.NAME), m.Option(LINK)) }},
|
||||
MERGE: {Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Echo(kit.MergeURL2(m.Cmdv("", arg[0], CLIENT_URL), arg[1], arg[2:]))
|
||||
}},
|
||||
}, mdb.HashAction(mdb.SHORT, CLIENT_NAME, mdb.FIELD, "time,client.name,client.url", LOGHEADERS, ice.FALSE), mdb.ClearOnExitHashAction()), Hand: func(m *ice.Message, arg ...string) {
|
||||
}, mdb.HashAction(mdb.SHORT, CLIENT_NAME, mdb.FIELD, "time,client.name,client.url"), mdb.ClearOnExitHashAction()), Hand: func(m *ice.Message, arg ...string) {
|
||||
if len(arg) < 2 || arg[0] == "" || (len(arg) > 3 && arg[3] == "") {
|
||||
mdb.HashSelect(m, kit.Slice(arg, 0, 1)...).Sort(CLIENT_NAME)
|
||||
} else {
|
||||
@ -329,5 +300,5 @@ func SpideDelete(m *ice.Message, arg ...ice.Any) ice.Any {
|
||||
return kit.UnMarshal(m.Cmdx(http.MethodDelete, arg))
|
||||
}
|
||||
func SpideSave(m *ice.Message, file, link string, cb func(int, int, int)) *ice.Message {
|
||||
return m.Cmd("web.spide", ice.DEV, SPIDE_SAVE, file, http.MethodGet, link, cb)
|
||||
return m.Cmd(Prefix(SPIDE), ice.DEV, SPIDE_SAVE, file, http.MethodGet, link, cb)
|
||||
}
|
||||
|
@ -56,25 +56,22 @@ func (f *Frame) Start(m *ice.Message, arg ...string) {
|
||||
default:
|
||||
m.Cmd(tcp.SERVER, tcp.LISTEN, mdb.TYPE, HTTP, m.OptionSimple(mdb.NAME, tcp.HOST, tcp.PORT), func(l net.Listener) {
|
||||
defer mdb.HashCreateDeferRemove(m, m.OptionSimple(mdb.NAME, tcp.PROTO), arg, cli.STATUS, tcp.START)()
|
||||
gdb.EventDeferEvent(m, SERVE_START, arg)
|
||||
gdb.Event(m, SERVE_START, arg)
|
||||
m.Warn(f.Server.Serve(l))
|
||||
})
|
||||
}
|
||||
}
|
||||
func (f *Frame) Close(m *ice.Message, arg ...string) {}
|
||||
func (f *Frame) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
if _serve_main(f.Message, w, r) {
|
||||
f.ServeMux.ServeHTTP(w, r)
|
||||
}
|
||||
kit.If(_serve_main(f.Message, w, r), func() { f.ServeMux.ServeHTTP(w, r) })
|
||||
}
|
||||
|
||||
const WEB = "web"
|
||||
|
||||
var Index = &ice.Context{Name: WEB, Help: "网络模块"}
|
||||
|
||||
func init() {
|
||||
ice.Index.Register(Index, &Frame{}, BROAD, SERVE, SPACE, DREAM, SHARE, CACHE, SPIDE)
|
||||
}
|
||||
func init() { ice.Index.Register(Index, &Frame{}, BROAD, SERVE, SPACE, DREAM, CACHE, SPIDE, SHARE) }
|
||||
|
||||
func ApiAction(arg ...string) ice.Actions { return ice.Actions{kit.Select(ice.PS, arg, 0): {}} }
|
||||
func Prefix(arg ...string) string { return kit.Keys(WEB, arg) }
|
||||
|
||||
|
@ -7,7 +7,6 @@ import (
|
||||
"strings"
|
||||
|
||||
ice "shylinux.com/x/icebergs"
|
||||
"shylinux.com/x/icebergs/base/cli"
|
||||
"shylinux.com/x/icebergs/base/lex"
|
||||
"shylinux.com/x/icebergs/base/mdb"
|
||||
kit "shylinux.com/x/toolkits"
|
||||
@ -292,15 +291,15 @@ func (mat *Matrix) show(m *ice.Message) {
|
||||
}
|
||||
key, value := kit.Format("%v", mat.name(mat.hand, j)), []string{}
|
||||
if node := mat.mat[i][j]; node != nil {
|
||||
if node.star > 0 {
|
||||
value = append(value, cli.ColorYellow(m, mat.name(mat.hand, node.star)))
|
||||
}
|
||||
if node.next > 0 {
|
||||
value = append(value, cli.ColorGreen(m, node.next))
|
||||
}
|
||||
if node.hash > 0 {
|
||||
value = append(value, cli.ColorRed(m, mat.name(mat.hand, node.hash)))
|
||||
}
|
||||
// if node.star > 0 {
|
||||
// value = append(value, cli.ColorYellow(m, mat.name(mat.hand, node.star)))
|
||||
// }
|
||||
// if node.next > 0 {
|
||||
// value = append(value, cli.ColorGreen(m, node.next))
|
||||
// }
|
||||
// if node.hash > 0 {
|
||||
// value = append(value, cli.ColorRed(m, mat.name(mat.hand, node.hash)))
|
||||
// }
|
||||
}
|
||||
m.Push(key, strings.Join(value, ","))
|
||||
}
|
||||
|
@ -15,10 +15,6 @@ import (
|
||||
|
||||
func _cmd_file(m *ice.Message, arg ...string) bool {
|
||||
switch p := path.Join(arg...); kit.Ext(p) {
|
||||
case nfs.ZML:
|
||||
web.RenderCmd(m, CAN_PARSE, m.Cmdx(nfs.CAT, p))
|
||||
case nfs.IML:
|
||||
m.RenderRedirect(web.MergePodWebSite(m, "", strings.TrimPrefix(p, SRC_WEBSITE)))
|
||||
case nfs.SHY:
|
||||
web.RenderCmd(m, "web.wiki.word", p)
|
||||
case nfs.GO:
|
||||
|
@ -18,7 +18,7 @@ func init() {
|
||||
GRANT: {Name: "grant space auto", Help: "授权", Actions: ice.MergeActions(ice.Actions{
|
||||
web.SPACE_LOGIN: {Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Go(func() {
|
||||
link := tcp.PublishLocalhost(m, web.MergePodCmd(m, "", "", web.SPACE, m.Option(mdb.NAME)))
|
||||
link := tcp.PublishLocalhost(m, m.MergePodCmd("", "", web.SPACE, m.Option(mdb.NAME)))
|
||||
m.Sleep300ms(web.SPACE, m.Option(mdb.NAME), cli.PWD, m.Option(mdb.NAME), link, m.Cmdx(cli.QRCODE, link))
|
||||
})
|
||||
}},
|
||||
|
@ -23,7 +23,7 @@ func init() {
|
||||
}
|
||||
switch arg[0] {
|
||||
case mdb.NAME:
|
||||
m.Push(arg[0], web.OptionUserWeb(m).Host)
|
||||
m.Push(arg[0], web.UserWeb(m).Host)
|
||||
case mdb.TEXT:
|
||||
m.Push(arg[0], m.Option(ice.MSG_USERWEB))
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ func KeyboardAction() ice.Actions {
|
||||
return ice.Actions{
|
||||
KEYBOARD: {Hand: func(m *ice.Message, arg ...string) {
|
||||
hash := m.Cmdx("web.chat.keyboard", mdb.CREATE, web.SPACE, m.Option(ice.MSG_DAEMON), ctx.INDEX, m.Option(ctx.INDEX), "input", "")
|
||||
link := tcp.PublishLocalhost(m, web.MergePodCmd(m, "", "web.chat.keyboard", mdb.HASH, hash))
|
||||
link := tcp.PublishLocalhost(m, m.MergePodCmd("", "web.chat.keyboard", mdb.HASH, hash))
|
||||
m.Push(mdb.NAME, link).PushQRCode(mdb.TEXT, link)
|
||||
}},
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ const POD = "pod"
|
||||
func init() {
|
||||
Index.MergeCommands(ice.Commands{
|
||||
POD: {Name: "pod", Help: "节点", Actions: ice.MergeActions(ctx.CmdAction(), web.ApiAction(), aaa.WhiteAction()), Hand: func(m *ice.Message, arg ...string) {
|
||||
if web.OptionAgentIs(m, "curl", "wget") {
|
||||
if web.AgentIs(m, "curl", "wget") {
|
||||
m.Cmdy(web.SHARE_LOCAL, ice.BIN_ICE_BIN, kit.Dict(ice.POD, kit.Select("", arg, 0), ice.MSG_USERROLE, aaa.TECH))
|
||||
return
|
||||
}
|
||||
@ -31,8 +31,6 @@ func init() {
|
||||
web.RenderMain(m)
|
||||
} else if arg[1] == CMD {
|
||||
web.RenderPodCmd(m, arg[0], arg[2], arg[3:])
|
||||
} else if arg[1] == WEBSITE {
|
||||
RenderWebsite(m, arg[0], path.Join(arg[2:]...))
|
||||
}
|
||||
}},
|
||||
})
|
||||
|
@ -5,7 +5,6 @@ import (
|
||||
|
||||
ice "shylinux.com/x/icebergs"
|
||||
"shylinux.com/x/icebergs/base/aaa"
|
||||
"shylinux.com/x/icebergs/base/cli"
|
||||
"shylinux.com/x/icebergs/base/mdb"
|
||||
"shylinux.com/x/icebergs/base/nfs"
|
||||
"shylinux.com/x/icebergs/base/web"
|
||||
@ -95,7 +94,7 @@ func init() {
|
||||
m.RenderDownload(p)
|
||||
return
|
||||
}
|
||||
m.Cmdy("", kit.TrimExt(kit.Select(cli.BLACK, arg, 0), nfs.CSS)).RenderResult().W.Header()[web.ContentType] = kit.Simple(web.ContentCSS)
|
||||
m.Cmdy("", kit.TrimExt(kit.Select(web.BLACK, arg, 0), nfs.CSS)).RenderResult().W.Header()[web.ContentType] = kit.Simple(web.ContentCSS)
|
||||
}},
|
||||
})
|
||||
}
|
||||
|
@ -1,251 +1 @@
|
||||
package chat
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
ice "shylinux.com/x/icebergs"
|
||||
"shylinux.com/x/icebergs/base/aaa"
|
||||
"shylinux.com/x/icebergs/base/ctx"
|
||||
"shylinux.com/x/icebergs/base/lex"
|
||||
"shylinux.com/x/icebergs/base/mdb"
|
||||
"shylinux.com/x/icebergs/base/nfs"
|
||||
"shylinux.com/x/icebergs/base/web"
|
||||
kit "shylinux.com/x/toolkits"
|
||||
)
|
||||
|
||||
func _website_url(m *ice.Message, file string) string {
|
||||
return strings.Split(web.MergePodWebSite(m, "", file), "?")[0]
|
||||
}
|
||||
func _website_parse(m *ice.Message, text string, args ...string) (ice.Map, bool) {
|
||||
if text == "" {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
const (
|
||||
HEADER = "Header"
|
||||
RIVER = "River"
|
||||
FOOTER = "Footer"
|
||||
|
||||
ORDER = "order"
|
||||
TITLE = "title"
|
||||
MENUS = "menus"
|
||||
)
|
||||
|
||||
river, storm, last := kit.Dict(
|
||||
HEADER, kit.Dict(MENUS, kit.List(), ctx.STYLE, kit.Dict(ctx.DISPLAY, "none")),
|
||||
RIVER, kit.Dict(MENUS, kit.List(), ctx.ACTION, kit.List("")),
|
||||
FOOTER, kit.Dict(MENUS, kit.List(), ctx.STYLE, kit.Dict(ctx.DISPLAY, "none")),
|
||||
args,
|
||||
), kit.Dict(), kit.Dict()
|
||||
|
||||
nriver, nstorm, prefix := 0, 0, ""
|
||||
m.Cmd(lex.SPLIT, "", mdb.KEY, mdb.NAME, kit.Dict(nfs.CAT_CONTENT, text), func(deep int, ls []string) {
|
||||
if deep == 1 {
|
||||
switch ls[0] {
|
||||
case HEADER, RIVER, FOOTER:
|
||||
for i := 1; i < len(ls); i += 2 {
|
||||
kit.Value(river, kit.Keys(ls[0], ls[i]), ls[i+1])
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
data := kit.Dict()
|
||||
switch kit.Ext(ls[0]) {
|
||||
case nfs.JS:
|
||||
ls[0], data[ctx.DISPLAY] = kit.Select(ice.CAN_PLUGIN, ctx.GetFileCmd(ls[0])), ctx.FileURI(ls[0])
|
||||
case nfs.GO:
|
||||
ls[0] = ctx.GetFileCmd(ls[0])
|
||||
case nfs.SHY:
|
||||
ls[0], data[ctx.ARGS] = "web.wiki.word", ls[0]
|
||||
case nfs.SH:
|
||||
ls[0], data[ctx.ARGS] = "web.code.sh.sh", ls[0]
|
||||
case nfs.PY:
|
||||
ls[0], data[ctx.ARGS] = "web.code.sh.py", ls[0]
|
||||
case "~":
|
||||
prefix, ls = ls[1], ls[1:]
|
||||
fallthrough
|
||||
case "-":
|
||||
for _, v := range ls[1:] {
|
||||
last[mdb.LIST] = append(last[mdb.LIST].([]ice.Any), kit.Dict(mdb.INDEX, kit.Keys(prefix, v)))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if ls[0] == "" {
|
||||
return
|
||||
} else if len(ls) == 1 && deep > 2 {
|
||||
ls = append(ls, m.Cmd(ctx.COMMAND, ls[0]).Append(mdb.HELP))
|
||||
} else if len(ls) == 1 {
|
||||
ls = append(ls, ls[0])
|
||||
} else if ls[1] == "" {
|
||||
ls[1] = ls[0]
|
||||
}
|
||||
|
||||
for i := 2; i < len(ls); i += 2 {
|
||||
switch ls[i] {
|
||||
case ctx.ARGS:
|
||||
data[ls[i]] = kit.Split(ls[i+1])
|
||||
case ctx.DISPLAY:
|
||||
// data[ls[i]] = ice.Display(ls[i+1])[ctx.DISPLAY]
|
||||
case ctx.STYLE, ctx.ACTION, TITLE, MENUS:
|
||||
data[ls[i]] = kit.UnMarshal(ls[i+1])
|
||||
default:
|
||||
data[ls[i]] = ls[i+1]
|
||||
}
|
||||
}
|
||||
|
||||
switch deep {
|
||||
case 1:
|
||||
if nriver++; ls[0] == ice.AUTO {
|
||||
ls[0] = kit.Format(nriver)
|
||||
}
|
||||
nstorm, storm = 0, kit.Dict()
|
||||
river[ls[0]] = kit.Dict(mdb.NAME, ls[1], STORM, storm, data, ORDER, len(river))
|
||||
case 2:
|
||||
if nstorm++; ls[0] == ice.AUTO {
|
||||
ls[0] = kit.Format(nstorm)
|
||||
}
|
||||
last = kit.Dict(mdb.NAME, ls[1], mdb.LIST, kit.List(), data, ORDER, len(storm))
|
||||
storm[ls[0]] = last
|
||||
prefix = ""
|
||||
default:
|
||||
last[mdb.LIST] = append(last[mdb.LIST].([]ice.Any), kit.Dict(mdb.NAME, kit.Select(ls[0], data[mdb.NAME]), mdb.HELP, ls[1], mdb.INDEX, ls[0], data))
|
||||
}
|
||||
})
|
||||
return river, true
|
||||
}
|
||||
func _website_render(m *ice.Message, w http.ResponseWriter, r *http.Request, kind, text, name string) bool {
|
||||
msg := m.Spawn(w, r)
|
||||
switch kind {
|
||||
case nfs.ZML:
|
||||
web.RenderCmd(msg, CAN_PARSE, text, name)
|
||||
case nfs.IML:
|
||||
res, _ := _website_parse(msg, text)
|
||||
msg.RenderResult(_website_template2, kit.Format(res))
|
||||
case nfs.SHY:
|
||||
if r.Method == http.MethodGet {
|
||||
web.RenderCmd(msg, msg.Prefix(DIV), text)
|
||||
} else {
|
||||
r.URL.Path = "/chat/cmd/web.chat.div"
|
||||
return false
|
||||
}
|
||||
case nfs.JS:
|
||||
msg.RenderResult(_website_template, text)
|
||||
case nfs.JSON:
|
||||
msg.RenderResult(_website_template2, kit.Format(kit.UnMarshal(text)))
|
||||
case nfs.HTML:
|
||||
msg.RenderResult(text)
|
||||
case nfs.SVG:
|
||||
msg.RenderResult(`<body style="background-color:cadetblue">%s</body>`, msg.Cmdx(nfs.CAT, text))
|
||||
default:
|
||||
msg.RenderDownload(text)
|
||||
}
|
||||
web.Render(msg, msg.Option(ice.MSG_OUTPUT), msg.Optionv(ice.MSG_ARGS).([]ice.Any)...)
|
||||
return true
|
||||
}
|
||||
|
||||
const (
|
||||
CAN_PARSE = "can.parse"
|
||||
SRC_WEBSITE = "src/website/"
|
||||
CHAT_WEBSITE = "/chat/website/"
|
||||
)
|
||||
const WEBSITE = "website"
|
||||
|
||||
func init() {
|
||||
Index.MergeCommands(ice.Commands{
|
||||
WEBSITE: {Name: "website path auto create import", Help: "网站", Actions: ice.MergeActions(ice.Actions{
|
||||
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmd(mdb.RENDER, mdb.CREATE, nfs.IML, m.PrefixKey())
|
||||
m.Cmd(mdb.ENGINE, mdb.CREATE, nfs.IML, m.PrefixKey())
|
||||
}},
|
||||
lex.PARSE: {Hand: func(m *ice.Message, arg ...string) {
|
||||
switch kit.Ext(arg[0]) {
|
||||
case nfs.ZML:
|
||||
web.RenderCmd(m, CAN_PARSE, m.Cmdx(nfs.CAT, path.Join(SRC_WEBSITE, arg[0])))
|
||||
case nfs.IML:
|
||||
if res, ok := _website_parse(m, m.Cmdx(nfs.CAT, path.Join(SRC_WEBSITE, arg[0])), arg[1:]...); ok {
|
||||
m.Echo(_website_template2, kit.Format(res))
|
||||
}
|
||||
default:
|
||||
if text := m.CmdAppend("", path.Join(ice.PS, arg[0]), mdb.TEXT); text != "" {
|
||||
if res, ok := _website_parse(m, text, arg[1:]...); ok {
|
||||
m.Echo(_website_template2, kit.Format(res))
|
||||
}
|
||||
}
|
||||
}
|
||||
}},
|
||||
mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) {
|
||||
switch m.Option(ctx.ACTION) {
|
||||
case mdb.CREATE:
|
||||
mdb.HashInputs(m, arg)
|
||||
return
|
||||
}
|
||||
switch arg[0] {
|
||||
case nfs.PATH:
|
||||
m.Cmdy(nfs.DIR, arg[1:]).ProcessAgain()
|
||||
}
|
||||
}},
|
||||
mdb.CREATE: {Name: "create path type=zml,iml,json,js,html name text"},
|
||||
mdb.IMPORT: {Name: "import path=src/website/", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmd(nfs.DIR, kit.Dict(nfs.DIR_ROOT, m.Option(nfs.PATH)), func(p string) {
|
||||
switch name := strings.TrimPrefix(p, m.Option(nfs.PATH)); kit.Ext(p) {
|
||||
case nfs.HTML, nfs.JS, nfs.JSON, nfs.ZML, nfs.IML, nfs.TXT:
|
||||
m.Cmd("", mdb.CREATE, nfs.PATH, path.Join(ice.PS, name), mdb.TYPE, kit.Ext(p), mdb.NAME, name, mdb.TEXT, m.Cmdx(nfs.CAT, p))
|
||||
default:
|
||||
m.Cmd("", mdb.CREATE, nfs.PATH, path.Join(ice.PS, name), mdb.TYPE, kit.Ext(p), mdb.NAME, name, mdb.TEXT, p)
|
||||
}
|
||||
})
|
||||
}},
|
||||
mdb.RENDER: {Hand: func(m *ice.Message, arg ...string) {
|
||||
m.EchoIFrame(_website_url(m, strings.TrimPrefix(path.Join(arg[2], arg[1]), SRC_WEBSITE)))
|
||||
}},
|
||||
mdb.ENGINE: {Hand: func(m *ice.Message, arg ...string) {
|
||||
if res, ok := _website_parse(m, m.Cmdx(nfs.CAT, path.Join(arg[2], arg[1]))); ok {
|
||||
ctx.DisplayStoryJSON(m.Echo(kit.Formats(res)))
|
||||
} else {
|
||||
m.Echo(_website_url(m, strings.TrimPrefix(path.Join(arg[2], arg[1]), SRC_WEBSITE)))
|
||||
}
|
||||
}},
|
||||
}, mdb.HashAction(mdb.SHORT, nfs.PATH, mdb.FIELD, "time,path,type,name,text"), ctx.CmdAction(), web.ApiAction(), aaa.WhiteAction()), Hand: func(m *ice.Message, arg ...string) {
|
||||
mdb.HashSelect(m, arg...).Table(func(value ice.Maps) { m.PushAnchor(web.MergePodWebSite(m, "", value[nfs.PATH])) })
|
||||
}},
|
||||
})
|
||||
}
|
||||
|
||||
func RenderWebsite(m *ice.Message, pod string, dir string, arg ...string) *ice.Message {
|
||||
return m.Echo(m.Cmdx(web.Space(m, pod), "web.chat.website", lex.PARSE, dir, arg)).RenderResult()
|
||||
}
|
||||
|
||||
var _website_template = `<!DOCTYPE html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width,initial-scale=0.8,maximum-scale=0.8,user-scalable=no"/>
|
||||
<meta charset="utf-8">
|
||||
<title>volcanos</title>
|
||||
<link rel="stylesheet" type="text/css" href="/index.css">
|
||||
<link rel="stylesheet" type="text/css" href="/page/cache.css">
|
||||
<link rel="shortcut icon" type="image/ico" href="/favicon.ico">
|
||||
</head>
|
||||
<body>
|
||||
<script src="/proto.js"></script>
|
||||
<script src="/page/cache.js"></script>
|
||||
<script>%s</script>
|
||||
</body>
|
||||
`
|
||||
var _website_template2 = `<!DOCTYPE html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width,initial-scale=0.8,maximum-scale=0.8,user-scalable=no"/>
|
||||
<meta charset="utf-8">
|
||||
<title>volcanos</title>
|
||||
<link rel="stylesheet" type="text/css" href="/index.css">
|
||||
<link rel="stylesheet" type="text/css" href="/page/cache.css">
|
||||
<link rel="shortcut icon" type="image/ico" href="/favicon.ico">
|
||||
</head>
|
||||
<body>
|
||||
<script src="/proto.js"></script>
|
||||
<script src="/page/cache.js"></script>
|
||||
<script>Volcanos({river: JSON.parse('%s')})</script>
|
||||
</body>
|
||||
`
|
||||
|
@ -82,7 +82,7 @@ func _autogen_git(m *ice.Message, arg ...string) ice.Map {
|
||||
)
|
||||
}
|
||||
func _autogen_mod(m *ice.Message, file string) (mod string) {
|
||||
host := web.OptionUserWeb(m).Hostname()
|
||||
host := web.UserWeb(m).Hostname()
|
||||
if host == "" {
|
||||
host = path.Base(kit.Path(""))
|
||||
} else {
|
||||
|
@ -44,7 +44,7 @@ func init() {
|
||||
m.Echo(ice.OK)
|
||||
}},
|
||||
ice.RUN: {Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Option(web.SPIDE_HEADER, web.ContentType, web.ContentJSON, web.UserAgent, "Mozilla/5.0")
|
||||
m.Option(web.SPIDE_HEADER, web.ContentType, web.ApplicationJSON, web.UserAgent, "Mozilla/5.0")
|
||||
m.Cmdy(web.SPIDE, m.Option(ice.DEV), web.SPIDE_RAW, m.Option(ice.CMD), m.Option(cli.API), web.SPIDE_DATA, m.Option(ice.ARG)).ProcessInner()
|
||||
m.StatusTime(nfs.SCRIPT, `curl "`+kit.MergeURL2(m.Cmd(web.SPIDE, m.Option(ice.DEV)).Append(web.CLIENT_ORIGIN), m.Option(cli.API))+`" -H "Content-Type: application/json"`+` -d '`+m.Option(ice.ARG)+`'`)
|
||||
}},
|
||||
|
@ -162,7 +162,6 @@ func init() {
|
||||
web.DOWNLOAD: {Name: "download link* path", Hand: func(m *ice.Message, arg ...string) { _install_download(m) }},
|
||||
cli.BUILD: {Name: "build link*", Hand: func(m *ice.Message, arg ...string) {
|
||||
web.PushStream(m)
|
||||
defer m.ProcessHold()
|
||||
if err := _install_build(m, arg...); m.Warn(err != "", err) {
|
||||
web.ToastFailure(m, cli.BUILD, err)
|
||||
} else {
|
||||
|
@ -23,7 +23,7 @@ func init() {
|
||||
API_GITHUB = "https://api.github.com/"
|
||||
)
|
||||
_oauth_header := func(m *ice.Message, arg ...string) *ice.Message {
|
||||
m.Option(web.SPIDE_HEADER, web.Accept, web.ContentJSON, web.Authorization, "token "+kit.Select(m.Option(ACCESS_TOKEN), arg, 0))
|
||||
m.Option(web.SPIDE_HEADER, web.Accept, web.ApplicationJSON, web.Authorization, "token "+kit.Select(m.Option(ACCESS_TOKEN), arg, 0))
|
||||
return m
|
||||
}
|
||||
Index.MergeCommands(ice.Commands{
|
||||
|
@ -49,7 +49,7 @@ func init() {
|
||||
m.Echo(m.Option(mdb.TEXT)).ProcessInner()
|
||||
}},
|
||||
web.SERVE: {Help: "展示", Hand: func(m *ice.Message, arg ...string) {
|
||||
u := web.OptionUserWeb(m)
|
||||
u := web.UserWeb(m)
|
||||
p := u.Hostname() + ice.DF + m.Cmdx(tcp.PORT, aaa.RIGHT)
|
||||
m.Cmd(cli.DAEMON, mdb.Configv(m, PPROF), "-http="+p, m.Option(BINNARY), m.Option(nfs.FILE))
|
||||
m.Sleep3s().ProcessOpen(kit.Format("http://%s/ui/top", p))
|
||||
|
@ -48,7 +48,7 @@ func init() {
|
||||
})
|
||||
if web.ToastSuccess(m); m.Option(ice.EXIT) == ice.TRUE {
|
||||
m.Cmd("", cli.RESTART)
|
||||
web.ToastRestart(m)
|
||||
web.Toast(m, cli.RESTART)
|
||||
}
|
||||
}},
|
||||
}})
|
||||
|
@ -64,7 +64,7 @@ func init() {
|
||||
m.PushSearch(mdb.TYPE, nfs.FILE, mdb.NAME, "main", mdb.TEXT, ice.SRC_MAIN_SH)
|
||||
m.PushSearch(mdb.TYPE, nfs.FILE, mdb.NAME, "main", mdb.TEXT, ice.SRC_MAIN_JS)
|
||||
m.PushSearch(mdb.TYPE, web.LINK, mdb.NAME, "admin", mdb.TEXT, kit.MergeURL(web.UserHost(m)+ice.PS, log.DEBUG, ice.TRUE))
|
||||
m.PushSearch(mdb.TYPE, web.LINK, mdb.NAME, m.CommandKey(), mdb.TEXT, web.MergePodCmds(m, "", "", log.DEBUG, ice.TRUE))
|
||||
m.PushSearch(mdb.TYPE, web.LINK, mdb.NAME, m.CommandKey(), mdb.TEXT, m.MergePodCmd("", "", log.DEBUG, ice.TRUE))
|
||||
}
|
||||
}},
|
||||
mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) {
|
||||
|
@ -2,12 +2,9 @@ package code
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
pty "shylinux.com/x/creackpty"
|
||||
ice "shylinux.com/x/icebergs"
|
||||
"shylinux.com/x/icebergs/base/cli"
|
||||
"shylinux.com/x/icebergs/base/ctx"
|
||||
@ -16,51 +13,33 @@ import (
|
||||
"shylinux.com/x/icebergs/base/nfs"
|
||||
"shylinux.com/x/icebergs/base/ssh"
|
||||
"shylinux.com/x/icebergs/base/web"
|
||||
"shylinux.com/x/icebergs/misc/xterm"
|
||||
kit "shylinux.com/x/toolkits"
|
||||
)
|
||||
|
||||
type _xterm struct {
|
||||
*exec.Cmd
|
||||
*os.File
|
||||
}
|
||||
|
||||
func (s _xterm) Setsize(rows, cols string) error {
|
||||
return pty.Setsize(s.File, &pty.Winsize{Rows: uint16(kit.Int(rows)), Cols: uint16(kit.Int(cols))})
|
||||
}
|
||||
func (s _xterm) Writeln(data string, arg ...ice.Any) {
|
||||
s.Write(kit.Format(data, arg...) + ice.NL)
|
||||
}
|
||||
func (s _xterm) Write(data string) (int, error) {
|
||||
return s.File.Write([]byte(data))
|
||||
}
|
||||
func (s _xterm) Close() error {
|
||||
return s.Cmd.Process.Kill()
|
||||
}
|
||||
func _xterm_get(m *ice.Message, h string) _xterm {
|
||||
func _xterm_get(m *ice.Message, h string) xterm.XTerm {
|
||||
h = kit.Select(m.Option(mdb.HASH), h)
|
||||
m.Assert(h != "")
|
||||
mdb.HashModify(m, mdb.TIME, m.Time(), web.VIEW, m.Option(ice.MSG_DAEMON))
|
||||
return mdb.HashSelectTarget(m, h, func(value ice.Maps) ice.Any {
|
||||
text := strings.Split(value[mdb.TEXT], ice.NL)
|
||||
ls := kit.Split(strings.Split(kit.Select(nfs.SH, value[mdb.TYPE]), " # ")[0])
|
||||
cmd := exec.Command(cli.SystemFind(m, ls[0]), ls[1:]...)
|
||||
cmd.Dir = nfs.MkdirAll(m, kit.Path(value[nfs.PATH]))
|
||||
cmd.Env = append(cmd.Env, os.Environ()...)
|
||||
cmd.Env = append(cmd.Env, "TERM=xterm")
|
||||
tty, err := pty.Start(cmd)
|
||||
m.Assert(err)
|
||||
term, e := xterm.Command(m, value[nfs.PATH], cli.SystemFind(m, ls[0]), ls[1:]...)
|
||||
if m.Warn(e) {
|
||||
return
|
||||
}
|
||||
m.Go(func() {
|
||||
defer tty.Close()
|
||||
defer term.Close()
|
||||
defer mdb.HashRemove(m, mdb.HASH, h)
|
||||
m.Log(cli.START, strings.Join(cmd.Args, ice.SP))
|
||||
m.Log("start", strings.Join(term.Args, ice.SP))
|
||||
buf := make([]byte, ice.MOD_BUFS)
|
||||
for {
|
||||
if n, e := tty.Read(buf); !m.Warn(e) && e == nil {
|
||||
if n, e := term.Read(buf); !m.Warn(e) && e == nil {
|
||||
if _xterm_echo(m, h, string(buf[:n])); len(text) > 0 {
|
||||
if cmd := text[0]; text[0] != "" {
|
||||
m.Go(func() {
|
||||
m.Sleep30ms()
|
||||
tty.Write([]byte(cmd + ice.NL))
|
||||
term.Write(cmd + ice.NL)
|
||||
})
|
||||
}
|
||||
text = text[1:]
|
||||
@ -71,8 +50,8 @@ func _xterm_get(m *ice.Message, h string) _xterm {
|
||||
}
|
||||
}
|
||||
})
|
||||
return _xterm{cmd, tty}
|
||||
}).(_xterm)
|
||||
return term
|
||||
}).(xterm.XTerm)
|
||||
}
|
||||
func _xterm_echo(m *ice.Message, h string, str string) {
|
||||
m.Options(ice.MSG_DAEMON, mdb.HashSelectField(m, h, web.VIEW))
|
||||
@ -90,7 +69,7 @@ func init() {
|
||||
XTERM: {Name: "xterm hash auto", Help: "命令行", Actions: ice.MergeActions(ice.Actions{
|
||||
mdb.SEARCH: {Hand: func(m *ice.Message, arg ...string) {
|
||||
if arg[0] == mdb.FOREACH && arg[1] == "" {
|
||||
m.PushSearch(mdb.TYPE, web.LINK, mdb.NAME, m.CommandKey(), mdb.TEXT, web.MergePodCmds(m, "", "", log.DEBUG, ice.TRUE))
|
||||
m.PushSearch(mdb.TYPE, web.LINK, mdb.NAME, m.CommandKey(), mdb.TEXT, m.MergePodCmd("", "", log.DEBUG, ice.TRUE))
|
||||
}
|
||||
}},
|
||||
mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) {
|
||||
@ -126,7 +105,7 @@ func init() {
|
||||
}
|
||||
}},
|
||||
web.OUTPUT: {Help: "全屏", Hand: func(m *ice.Message, arg ...string) {
|
||||
web.ProcessWebsite(m, "", "", m.OptionSimple(mdb.HASH), ctx.STYLE, web.OUTPUT)
|
||||
web.ProcessPodCmd(m, "", "", m.OptionSimple(mdb.HASH), ctx.STYLE, web.OUTPUT)
|
||||
}},
|
||||
web.DREAM_CREATE: {Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmd("", mdb.CREATE, mdb.TYPE, BASH, m.OptionSimple(mdb.NAME), nfs.PATH, path.Join(ice.USR_LOCAL_WORK, m.Option(mdb.NAME)))
|
||||
|
109
core/code/zml.go
109
core/code/zml.go
@ -1,110 +1 @@
|
||||
package code
|
||||
|
||||
import (
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
ice "shylinux.com/x/icebergs"
|
||||
"shylinux.com/x/icebergs/base/ctx"
|
||||
"shylinux.com/x/icebergs/base/mdb"
|
||||
"shylinux.com/x/icebergs/base/nfs"
|
||||
"shylinux.com/x/icebergs/base/web"
|
||||
kit "shylinux.com/x/toolkits"
|
||||
)
|
||||
|
||||
func _website_url(m *ice.Message, file string) string {
|
||||
return strings.Split(web.MergePodWebSite(m, "", file), "?")[0]
|
||||
}
|
||||
|
||||
const ZML = nfs.ZML
|
||||
|
||||
func init() {
|
||||
const (
|
||||
SRC_WEBSITE = "src/website/"
|
||||
)
|
||||
Index.MergeCommands(ice.Commands{
|
||||
ZML: {Name: "zml", Help: "网页", Actions: ice.MergeActions(ice.Actions{
|
||||
mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) {}},
|
||||
TEMPLATE: {Hand: func(m *ice.Message, arg ...string) {
|
||||
switch kit.Ext(m.Option(mdb.FILE)) {
|
||||
case ZML:
|
||||
m.Echo(`
|
||||
{
|
||||
username
|
||||
系统
|
||||
命令 index cli.system
|
||||
共享 index cli.qrcode
|
||||
代码
|
||||
趋势 index web.code.git.trend args icebergs action auto
|
||||
状态 index web.code.git.status args icebergs
|
||||
脚本
|
||||
终端 index hi/hi.sh
|
||||
文档 index hi/hi.shy
|
||||
数据 index hi/hi.py
|
||||
后端 index hi/hi.go
|
||||
前端 index hi/hi.js
|
||||
}
|
||||
`)
|
||||
case nfs.IML:
|
||||
m.Echo(`
|
||||
系统
|
||||
命令
|
||||
cli.system
|
||||
环境
|
||||
cli.runtime
|
||||
开发
|
||||
模块
|
||||
hi/hi.go
|
||||
脚本
|
||||
hi/hi.sh
|
||||
hi/hi.shy
|
||||
hi/hi.py
|
||||
hi/hi.go
|
||||
hi/hi.js
|
||||
`)
|
||||
}
|
||||
}},
|
||||
COMPLETE: {Hand: func(m *ice.Message, arg ...string) {
|
||||
if len(arg) > 0 && arg[0] == mdb.FOREACH {
|
||||
switch m.Option(ctx.ACTION) {
|
||||
case web.WEBSITE:
|
||||
m.Cmdy(nfs.DIR, nfs.PWD, kit.Dict(nfs.DIR_ROOT, SRC_WEBSITE), nfs.PATH)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
switch kit.Select("", kit.Slice(kit.Split(m.Option(mdb.TEXT), "\t \n`"), -1), 0) {
|
||||
case mdb.TYPE:
|
||||
m.Push(mdb.NAME, "menu")
|
||||
|
||||
case ctx.INDEX:
|
||||
m.Cmdy(ctx.COMMAND, mdb.SEARCH, ctx.COMMAND, "", "", ice.OptionFields("index,name,text"))
|
||||
|
||||
case ctx.ACTION:
|
||||
m.Push(mdb.NAME, "auto")
|
||||
m.Push(mdb.NAME, "push")
|
||||
m.Push(mdb.NAME, "open")
|
||||
|
||||
default:
|
||||
if strings.HasSuffix(m.Option(mdb.TEXT), ice.SP) {
|
||||
m.Push(mdb.NAME, "index")
|
||||
m.Push(mdb.NAME, "action")
|
||||
m.Push(mdb.NAME, "args")
|
||||
m.Push(mdb.NAME, "type")
|
||||
} else if m.Option(mdb.TEXT) == "" {
|
||||
m.Push(mdb.NAME, "head")
|
||||
m.Push(mdb.NAME, "left")
|
||||
m.Push(mdb.NAME, "main")
|
||||
m.Push(mdb.NAME, "foot")
|
||||
}
|
||||
}
|
||||
}},
|
||||
mdb.RENDER: {Hand: func(m *ice.Message, arg ...string) {
|
||||
m.EchoIFrame(_website_url(m, strings.TrimPrefix(path.Join(arg[2], arg[1]), SRC_WEBSITE)))
|
||||
}},
|
||||
mdb.ENGINE: {Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Echo(_website_url(m, strings.TrimPrefix(path.Join(arg[2], arg[1]), SRC_WEBSITE)))
|
||||
}},
|
||||
}, PlugAction())},
|
||||
})
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ import (
|
||||
"shylinux.com/x/icebergs/base/ctx"
|
||||
"shylinux.com/x/icebergs/base/mdb"
|
||||
"shylinux.com/x/icebergs/base/web"
|
||||
kit "shylinux.com/x/toolkits"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -28,10 +27,10 @@ func init() {
|
||||
m.PushAction("copy", mdb.MODIFY, mdb.REMOVE)
|
||||
ctx.DisplayLocal(m, "")
|
||||
} else {
|
||||
for _, p := range kit.Split(m.Append("image")) {
|
||||
m.EchoImages(web.MergeURL2(m, web.SHARE_CACHE+p))
|
||||
}
|
||||
m.PushAction("play", "stop", "copy", mdb.MODIFY, mdb.REMOVE)
|
||||
// for _, p := range kit.Split(m.Append("image")) {
|
||||
// m.EchoImages(web.MergeURL2(m, web.SHARE_CACHE+p))
|
||||
// }
|
||||
// m.PushAction("play", "stop", "copy", mdb.MODIFY, mdb.REMOVE)
|
||||
}
|
||||
}},
|
||||
})
|
||||
|
@ -86,13 +86,14 @@ func _status_each(m *ice.Message, title string, cmds ...string) {
|
||||
ReposList(m).Table(func(value ice.Maps) {
|
||||
toast(value[REPOS], count, total)
|
||||
if msg := m.Cmd(cmds, kit.Dict(cli.CMD_DIR, value[nfs.PATH])); !cli.IsSuccess(msg) {
|
||||
web.Toast3s(m, msg.Append(cli.CMD_ERR)+msg.Append(cli.CMD_OUT), "error: "+value[REPOS]).Sleep3s()
|
||||
web.Toast(m, msg.Append(cli.CMD_ERR)+msg.Append(cli.CMD_OUT), "error: "+value[REPOS], "", "3s")
|
||||
m.Sleep3s()
|
||||
list = append(list, value[REPOS])
|
||||
}
|
||||
count++
|
||||
})
|
||||
if len(list) > 0 {
|
||||
web.Toast30s(m, strings.Join(list, ice.NL), ice.FAILURE)
|
||||
web.Toast(m, strings.Join(list, ice.NL), ice.FAILURE, "30s")
|
||||
} else {
|
||||
toast(ice.SUCCESS, count, total)
|
||||
}
|
||||
|
@ -13,12 +13,12 @@ import (
|
||||
)
|
||||
|
||||
func _lark_get(m *ice.Message, appid string, arg ...ice.Any) (*ice.Message, ice.Any) {
|
||||
m.Option(web.SPIDE_HEADER, "Authorization", "Bearer "+m.Cmdx(APP, TOKEN, appid), web.ContentType, web.ContentJSON)
|
||||
m.Option(web.SPIDE_HEADER, "Authorization", "Bearer "+m.Cmdx(APP, TOKEN, appid), web.ContentType, web.ApplicationJSON)
|
||||
msg := m.Cmd(web.SPIDE, LARK, http.MethodGet, arg)
|
||||
return msg, msg.Optionv(web.SPIDE_RES)
|
||||
}
|
||||
func _lark_post(m *ice.Message, appid string, arg ...ice.Any) *ice.Message {
|
||||
m.Option(web.SPIDE_HEADER, "Authorization", "Bearer "+m.Cmdx(APP, TOKEN, appid), web.ContentType, web.ContentJSON)
|
||||
m.Option(web.SPIDE_HEADER, "Authorization", "Bearer "+m.Cmdx(APP, TOKEN, appid), web.ContentType, web.ApplicationJSON)
|
||||
return m.Cmd(web.SPIDE, LARK, arg)
|
||||
}
|
||||
func _lark_parse(m *ice.Message) {
|
||||
|
14
misc/qrcode/qrcode.go
Normal file
14
misc/qrcode/qrcode.go
Normal file
@ -0,0 +1,14 @@
|
||||
package qrcode
|
||||
|
||||
import (
|
||||
"shylinux.com/x/go-qrcode"
|
||||
)
|
||||
|
||||
type QRCode struct {
|
||||
*qrcode.QRCode
|
||||
}
|
||||
|
||||
func New(text string) *QRCode {
|
||||
qr, _ := qrcode.New(text, qrcode.Medium)
|
||||
return &QRCode{qr}
|
||||
}
|
@ -188,7 +188,7 @@ func init() {
|
||||
}
|
||||
}},
|
||||
aaa.INVITE: {Help: "邀请", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Option(cli.HOSTNAME, tcp.PublishLocalhost(m, web.OptionUserWeb(m).Hostname()))
|
||||
m.Option(cli.HOSTNAME, tcp.PublishLocalhost(m, web.UserWeb(m).Hostname()))
|
||||
if buf, err := kit.Render(`ssh -p {{.Option "port"}} {{.Option "user.name"}}@{{.Option "hostname"}}`, m); err == nil {
|
||||
m.EchoScript(string(buf))
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ func init() {
|
||||
}},
|
||||
}, Hand: func(m *ice.Message, arg ...string) {
|
||||
if kit.If(len(arg) > 1 && arg[0] != "" && arg[1] != "", func() { _tmux_cmd(m, SET_BUFFER, "-b", arg[0], arg[1]) }); len(arg) > 0 && arg[0] != "" {
|
||||
cli.PushText(m, _tmux_cmds(m, SHOW_BUFFER, "-b", arg[0]))
|
||||
PushText(m, _tmux_cmds(m, SHOW_BUFFER, "-b", arg[0]))
|
||||
return
|
||||
}
|
||||
for i, v := range kit.SplitLine(_tmux_cmd(m, LIST_BUFFER).Result()) {
|
||||
@ -47,7 +47,15 @@ func init() {
|
||||
}},
|
||||
TEXT: {Name: "text auto text:textarea", Help: "文本", Hand: func(m *ice.Message, arg ...string) {
|
||||
kit.If(len(arg) > 0, func() { _tmux_cmd(m, SET_BUFFER, arg[0]) })
|
||||
cli.PushText(m, _tmux_cmds(m, SHOW_BUFFER))
|
||||
PushText(m, _tmux_cmds(m, SHOW_BUFFER))
|
||||
}},
|
||||
})
|
||||
}
|
||||
func PushText(m *ice.Message, text string) {
|
||||
m.OptionFields(ice.MSG_DETAIL)
|
||||
if m.PushScript(nfs.SCRIPT, text); strings.HasPrefix(text, ice.HTTP) {
|
||||
m.PushQRCode(cli.QRCODE, text)
|
||||
m.PushAnchor(text)
|
||||
}
|
||||
m.Echo(text)
|
||||
}
|
||||
|
@ -65,10 +65,10 @@ func init() {
|
||||
Qrcode(m, args[1])
|
||||
case wiki.FIELD:
|
||||
m.Option(ice.MSG_USERWEB, m.Cmdx(web.SPACE, web.DOMAIN))
|
||||
Qrcode(m, web.MergePodCmd(m, "", kit.Select(args[1], args, 2)))
|
||||
Qrcode(m, m.MergePodCmd("", kit.Select(args[1], args, 2)))
|
||||
default:
|
||||
m.Option(ice.MSG_USERWEB, m.Cmdx(web.SPACE, web.DOMAIN))
|
||||
Qrcode(m, web.MergePodCmd(m, "", args[0]))
|
||||
Qrcode(m, m.MergePodCmd("", args[0]))
|
||||
}
|
||||
}},
|
||||
nfs.SOURCE: {Hand: func(m *ice.Message, arg ...string) {
|
||||
|
21
misc/websocket/websocket.go
Normal file
21
misc/websocket/websocket.go
Normal file
@ -0,0 +1,21 @@
|
||||
package websocket
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
ice "shylinux.com/x/icebergs"
|
||||
"shylinux.com/x/websocket"
|
||||
)
|
||||
|
||||
type Conn struct{ *websocket.Conn }
|
||||
|
||||
func Upgrade(w http.ResponseWriter, r *http.Request) (*Conn, error) {
|
||||
conn, e := websocket.Upgrade(w, r, nil, ice.MOD_BUFS, ice.MOD_BUFS)
|
||||
return &Conn{conn}, e
|
||||
}
|
||||
func NewClient(c net.Conn, u *url.URL) (*Conn, error) {
|
||||
conn, _, e := websocket.NewClient(c, u, nil, ice.MOD_BUFS, ice.MOD_BUFS)
|
||||
return &Conn{conn}, e
|
||||
}
|
37
misc/xterm/xterm.go
Normal file
37
misc/xterm/xterm.go
Normal file
@ -0,0 +1,37 @@
|
||||
package xterm
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/exec"
|
||||
|
||||
pty "shylinux.com/x/creackpty"
|
||||
ice "shylinux.com/x/icebergs"
|
||||
"shylinux.com/x/icebergs/base/nfs"
|
||||
kit "shylinux.com/x/toolkits"
|
||||
)
|
||||
|
||||
type XTerm struct {
|
||||
*exec.Cmd
|
||||
*os.File
|
||||
}
|
||||
|
||||
func (s XTerm) Setsize(rows, cols string) error {
|
||||
return pty.Setsize(s.File, &pty.Winsize{Rows: uint16(kit.Int(rows)), Cols: uint16(kit.Int(cols))})
|
||||
}
|
||||
func (s XTerm) Writeln(data string, arg ...ice.Any) {
|
||||
s.Write(kit.Format(data, arg...) + ice.NL)
|
||||
}
|
||||
func (s XTerm) Write(data string) (int, error) {
|
||||
return s.File.Write([]byte(data))
|
||||
}
|
||||
func (s XTerm) Close() error {
|
||||
return s.Cmd.Process.Kill()
|
||||
}
|
||||
func Command(m *ice.Message, dir string, cli string, arg ...string) (XTerm, error) {
|
||||
cmd := exec.Command(cli, arg...)
|
||||
cmd.Dir = nfs.MkdirAll(m, kit.Path(dir))
|
||||
cmd.Env = append(cmd.Env, os.Environ()...)
|
||||
cmd.Env = append(cmd.Env, "TERM=xterm")
|
||||
tty, err := pty.Start(cmd)
|
||||
return XTerm{cmd, tty}, err
|
||||
}
|
@ -38,6 +38,11 @@ func (m *Message) OptionCB(key string, cb ...Any) Any {
|
||||
return m.Optionv(kit.Keycb(kit.Select(m.CommandKey(), key)))
|
||||
}
|
||||
|
||||
func (m *Message) MergePod(pod string, arg ...Any) string {
|
||||
ls := []string{"chat"}
|
||||
kit.If(kit.Keys(m.Option(MSG_USERPOD), pod), func(p string) { ls = append(ls, POD, p) })
|
||||
return kit.MergeURL2(strings.Split(kit.Select(Info.Domain, m.Option(MSG_USERWEB)), QS)[0], PS+kit.Join(ls, PS), arg...)
|
||||
}
|
||||
func (m *Message) MergePodCmd(pod, cmd string, arg ...Any) string {
|
||||
ls := []string{"chat"}
|
||||
kit.If(kit.Keys(m.Option(MSG_USERPOD), pod), func(p string) { ls = append(ls, POD, p) })
|
||||
|
Loading…
x
Reference in New Issue
Block a user