1
0
forked from x/icebergs

add chrome.spided

This commit is contained in:
shaoying 2020-08-16 18:28:48 +08:00
parent 3b3eb31b77
commit 6b90e61e1e
20 changed files with 668 additions and 331 deletions

View File

@ -28,7 +28,7 @@ func _daemon_show(m *ice.Message, cmd *exec.Cmd, out, err string) {
}
cmd.Env = append(cmd.Env, fmt.Sprintf("PATH=%s", os.Getenv("PATH")))
if e := cmd.Start(); m.Warn(e != nil, "%v start: %s", cmd.Args, e) {
if e := cmd.Start(); m.Warn(e != nil, ice.ErrStart, cmd.Args, " ", e) {
return
}
@ -42,7 +42,7 @@ func _daemon_show(m *ice.Message, cmd *exec.Cmd, out, err string) {
m.Gos(m, func(m *ice.Message) {
if e := cmd.Wait(); e != nil {
m.Warn(e != nil, "%v wait: %s", cmd.Args, e)
m.Warn(e != nil, ice.ErrStart, cmd.Args, " ", e)
m.Richs(DAEMON, nil, h, func(key string, value map[string]interface{}) {
kit.Value(value, kit.MDB_STATUS, StatusError)
kit.Value(value, kit.Keys(kit.MDB_EXTRA, kit.MDB_ERROR), e)
@ -61,28 +61,38 @@ const DAEMON = "daemon"
func init() {
Index.Merge(&ice.Context{
Configs: map[string]*ice.Config{
DAEMON: {Name: "daemon", Help: "守护进程", Value: kit.Data()},
DAEMON: {Name: DAEMON, Help: "守护进程", Value: kit.Data(kit.MDB_PATH, "var/daemon")},
},
Commands: map[string]*ice.Command{
DAEMON: {Name: "daemon hash 查看:button=auto 清理:button", Help: "守护进程", Action: map[string]*ice.Action{
"delete": {Name: "delete", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy("mdb.delete", DAEMON, "", "hash", "hash", m.Option("hash"))
m.Richs(DAEMON, "", m.Option(kit.MDB_HASH), func(key string, value map[string]interface{}) {
m.Conf(DAEMON, kit.Keys(kit.MDB_HASH, key), "")
m.Log_DELETE(DAEMON, kit.Format(value))
})
}},
"prune": {Name: "prune", Help: "清理", Hand: func(m *ice.Message, arg ...string) {
m.Richs(DAEMON, "", kit.MDB_FOREACH, func(key string, value map[string]interface{}) {
if strings.Count(m.Cmdx(SYSTEM, "ps", value["pid"]), "\n") > 1 {
value["status"] = "start"
return
if strings.Count(m.Cmdx(SYSTEM, "ps", value[kit.MDB_PID]), "\n") == 1 {
m.Conf(DAEMON, kit.Keys(kit.MDB_HASH, key), "")
m.Log_DELETE(DAEMON, kit.Format(value))
}
})
}},
"stop": {Name: "stop", Help: "停止", Hand: func(m *ice.Message, arg ...string) {
m.Richs(DAEMON, "", m.Option(kit.MDB_HASH), func(key string, value map[string]interface{}) {
m.Cmdy(SYSTEM, "kill", value[kit.MDB_PID])
if strings.Count(m.Cmdx(SYSTEM, "ps", value[kit.MDB_PID]), "\n") == 1 {
value[kit.MDB_STATUS] = StatusClose
}
m.Conf(DAEMON, kit.Keys("hash", key), "")
})
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 {
m.Option("fields", "time,hash,status,pid,name,dir")
m.Cmdy("mdb.select", DAEMON, "", "hash")
m.Cmdy("mdb.select", DAEMON, "", kit.MDB_HASH)
m.Sort("time", "time_r")
m.PushAction("停止", "删除")
return
}

View File

@ -66,7 +66,7 @@ func _command_make(m *ice.Message, cmd *ice.Command) {
cmd.List = append(cmd.List, kit.List(kit.MDB_INPUT, "button", "name", "返回", "value", "Last")...)
button = true
default:
kind, value := "text", ""
kind, value := kit.Select("text", "button", button), ""
if len(ls) == 3 {
kind, value = ls[1], ls[2]
} else if len(ls) == 2 {

View File

@ -26,6 +26,12 @@ func _file_ext(name string) string {
func _file_list(m *ice.Message, root string, name string, level int, deep bool, dir_type string, dir_reg *regexp.Regexp, fields []string) {
switch strings.Split(name, "/")[0] {
case "etc", "var":
if m.Option(ice.MSG_USERROLE) == "root" {
break
}
if m.Option(ice.MSG_USERROLE) == "tech" {
break
}
return
}
@ -48,13 +54,14 @@ func _file_list(m *ice.Message, root string, name string, level int, deep bool,
}
p := path.Join(root, name, f.Name())
if f, e = os.Lstat(p); e != nil {
m.Log("info", "%s", e)
continue
} else if (f.Mode()&os.ModeSymlink) != 0 && f.IsDir() {
continue
}
// if f, e = os.Lstat(p); e != nil {
// m.Log("info", "%s", e)
// continue
// } else if (f.Mode()&os.ModeSymlink) != 0 && f.IsDir() {
// // continue
// } else {
// }
//
if !(dir_type == "file" && f.IsDir() || dir_type == "dir" && !f.IsDir()) && (dir_reg == nil || dir_reg.MatchString(f.Name())) {
for _, field := range fields {
switch field {
@ -93,7 +100,15 @@ func _file_list(m *ice.Message, root string, name string, level int, deep bool,
m.Push("tree", strings.Repeat("| ", level-1)+"|-"+f.Name())
}
case "size":
m.Push("size", kit.FmtSize(f.Size()))
if f.IsDir() {
if ls, e := ioutil.ReadDir(path.Join(root, name, f.Name())); e == nil {
m.Push("size", len(ls))
} else {
m.Push("size", 0)
}
} else {
m.Push("size", kit.FmtSize(f.Size()))
}
case "line":
if f.IsDir() {
if d, e := ioutil.ReadDir(p); m.Assert(e) {

View File

@ -105,6 +105,7 @@ func RenderStatus(msg *ice.Message, code int, text string) { // name path expire
var RENDER = struct {
A string
IMG string
Video string
Field string
Frame string
Button string
@ -113,6 +114,7 @@ var RENDER = struct {
}{
A: "a",
IMG: "img",
Video: "video",
Field: "field",
Frame: "frame",
Button: "button",
@ -132,6 +134,9 @@ func init() {
RENDER.IMG: {Hand: func(m *ice.Message, arg ...string) {
m.Echo(`<img src="%s" height=%s>`, arg[0], kit.Select("120", arg, 1))
}},
RENDER.Video: {Hand: func(m *ice.Message, arg ...string) {
m.Echo(`<video src="%s" height=%s controls>`, arg[0], kit.Select("120", arg, 1))
}},
RENDER.Field: {Hand: func(m *ice.Message, arg ...string) {
m.Echo(`<fieldset><legend>%s(%s)</legend><form></form></fieldset>`, arg[0], arg[1])
}},

View File

@ -114,7 +114,7 @@ func _space_send(m *ice.Message, space string, arg ...string) {
return nil
})
}
}) == nil, "not found %s", space)
}) == nil, ice.ErrNotFound, space)
}
func _space_echo(msg *ice.Message, source, target []string, c *websocket.Conn, name string) {

View File

@ -103,6 +103,37 @@ func _spide_render(m *ice.Message, kind, name, text string, arg ...string) {
}
const SPIDE = "spide"
const (
SPIDE_SHY = "shy"
SPIDE_DEV = "dev"
SPIDE_SELF = "self"
SPIDE_MSG = "msg"
SPIDE_RAW = "raw"
SPIDE_CACHE = "cache"
SPIDE_GET = "GET"
SPIDE_PUT = "PUT"
SPIDE_POST = "POST"
SPIDE_DELETE = "DELETE"
SPIDE_FILE = "file"
SPIDE_DATA = "data"
SPIDE_PART = "part"
SPIDE_FORM = "form"
SPIDE_JSON = "json"
SPIDE_CLIENT = "client"
SPIDE_HEADER = "header"
SPIDE_COOKIE = "cookie"
SPIDE_METHOD = "method"
ContentType = "Content-Type"
ContentLength = "Content-Length"
ContentFORM = "application/x-www-form-urlencoded"
ContentJSON = "application/json"
ContentHTML = "text/html"
)
func init() {
Index.Merge(&ice.Context{
@ -130,29 +161,29 @@ func init() {
}
m.Richs(SPIDE, nil, arg[0], func(key string, value map[string]interface{}) {
client := value["client"].(map[string]interface{})
client := value[SPIDE_CLIENT].(map[string]interface{})
// 缓存数据
cache := ""
switch arg[1] {
case "raw":
case SPIDE_MSG:
cache, arg = arg[1], arg[1:]
case "msg":
case SPIDE_RAW:
cache, arg = arg[1], arg[1:]
case "cache":
case SPIDE_CACHE:
cache, arg = arg[1], arg[1:]
}
// 请求方法
method := kit.Select("POST", client["method"])
method := kit.Select(SPIDE_POST, client[SPIDE_METHOD])
switch arg = arg[1:]; arg[0] {
case "GET":
method, arg = "GET", arg[1:]
case "PUT":
method, arg = "PUT", arg[1:]
case "POST":
method, arg = "POST", arg[1:]
case "DELETE":
method, arg = "DELETE", arg[1:]
case SPIDE_GET:
method, arg = SPIDE_GET, arg[1:]
case SPIDE_PUT:
method, arg = SPIDE_PUT, arg[1:]
case SPIDE_POST:
method, arg = SPIDE_POST, arg[1:]
case SPIDE_DELETE:
method, arg = SPIDE_DELETE, arg[1:]
}
// 请求地址
@ -161,18 +192,18 @@ func init() {
// 渲染引擎
head := map[string]string{}
body, ok := m.Optionv("body").(io.Reader)
if !ok && len(arg) > 0 && method != "GET" {
if !ok && len(arg) > 0 && method != SPIDE_GET {
switch arg[0] {
case "file":
case SPIDE_FILE:
if f, e := os.Open(arg[1]); m.Warn(e != nil, "%s", e) {
return
} else {
defer f.Close()
body, arg = f, arg[2:]
}
case "data":
case SPIDE_DATA:
body, arg = bytes.NewBufferString(arg[1]), arg[2:]
case "part":
case SPIDE_PART:
buf := &bytes.Buffer{}
mp := multipart.NewWriter(buf)
for i := 1; i < len(arg)-1; i += 2 {
@ -188,16 +219,16 @@ func init() {
}
}
mp.Close()
head["Content-Type"] = mp.FormDataContentType()
head[ContentType] = mp.FormDataContentType()
body = buf
case "form":
case SPIDE_FORM:
data := []string{}
for i := 1; i < len(arg)-1; i += 2 {
data = append(data, url.QueryEscape(arg[i])+"="+url.QueryEscape(arg[i+1]))
}
body = bytes.NewBufferString(strings.Join(data, "&"))
head["Content-Type"] = "application/x-www-form-urlencoded"
case "json":
head[ContentType] = ContentFORM
case SPIDE_JSON:
arg = arg[1:]
fallthrough
default:
@ -206,7 +237,7 @@ func init() {
kit.Value(data, arg[i], arg[i+1])
}
if b, e := json.Marshal(data); m.Assert(e) {
head["Content-Type"] = "application/json"
head[ContentType] = ContentJSON
body = bytes.NewBuffer(b)
}
m.Log(ice.LOG_EXPORT, "json: %s", kit.Format(data))
@ -223,14 +254,14 @@ func init() {
m.Assert(e)
// 请求变量
kit.Fetch(value["cookie"], func(key string, value string) {
kit.Fetch(value[SPIDE_COOKIE], func(key string, value string) {
req.AddCookie(&http.Cookie{Name: key, Value: value})
m.Info("%s: %s", key, value)
})
kit.Fetch(value["header"], func(key string, value string) {
kit.Fetch(value[SPIDE_HEADER], func(key string, value string) {
req.Header.Set(key, value)
})
list := kit.Simple(m.Optionv("header"))
list := kit.Simple(m.Optionv(SPIDE_HEADER))
for i := 0; i < len(list)-1; i += 2 {
req.Header.Set(list[i], list[i+1])
m.Info("%s: %s", list[i], list[i+1])
@ -244,7 +275,7 @@ func init() {
if web.Client == nil {
web.Client = &http.Client{Timeout: kit.Duration(kit.Format(client["timeout"]))}
}
m.Info("%s: %s", req.Header.Get("Content-Length"), req.Header.Get("Content-Type"))
m.Info("%s: %s", req.Header.Get(ContentLength), req.Header.Get(ContentType))
// 发送请求
res, e := web.Client.Do(req)
@ -253,7 +284,7 @@ func init() {
}
// 检查结果
m.Cost("%s %s: %s", res.Status, res.Header.Get("Content-Length"), res.Header.Get("Content-Type"))
m.Cost("%s %s: %s", res.Status, res.Header.Get(ContentLength), res.Header.Get(ContentType))
if m.Warn(res.StatusCode != http.StatusOK, "%s", res.Status) {
m.Set(ice.MSG_RESULT)
// return
@ -267,15 +298,15 @@ func init() {
// 解析引擎
switch cache {
case "cache":
case SPIDE_CACHE:
m.Optionv("response", res)
m.Cmdy(CACHE, DOWNLOAD, res.Header.Get("Content-Type"), uri)
m.Cmdy(CACHE, DOWNLOAD, res.Header.Get(ContentType), uri)
m.Echo(m.Append(DATA))
case "raw":
case SPIDE_RAW:
if b, e := ioutil.ReadAll(res.Body); m.Assert(e) {
m.Echo(string(b))
}
case "msg":
case SPIDE_MSG:
var data map[string][]string
m.Assert(json.NewDecoder(res.Body).Decode(&data))
m.Info("res: %s", kit.Formats(data))
@ -286,7 +317,7 @@ func init() {
}
m.Resultv(data[ice.MSG_RESULT])
default:
if strings.HasPrefix(res.Header.Get("Content-Type"), "text/html") {
if strings.HasPrefix(res.Header.Get(ContentType), ContentHTML) {
b, _ := ioutil.ReadAll(res.Body)
m.Echo(string(b))
break

View File

@ -197,4 +197,4 @@ export %s
},
}
func init() { web.Index.Register(Index, &web.Frame{}, COMPILE, UPGRADE, BENCH, PPROF) }
func init() { web.Index.Register(Index, &web.Frame{}, INSTALL, COMPILE, UPGRADE, BENCH, PPROF) }

View File

@ -1,15 +1,17 @@
package code
import (
"net/http"
"path"
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/cli"
"github.com/shylinux/icebergs/base/mdb"
"github.com/shylinux/icebergs/base/nfs"
"github.com/shylinux/icebergs/base/tcp"
"github.com/shylinux/icebergs/base/web"
kit "github.com/shylinux/toolkits"
"os"
"path"
"strings"
)
const INSTALL = "install"
@ -18,7 +20,7 @@ func init() {
Index.Merge(&ice.Context{
Configs: map[string]*ice.Config{
INSTALL: {Name: "install", Help: "安装", Value: kit.Data(
kit.MDB_SHORT, kit.MDB_NAME, "path", "usr/install",
kit.MDB_SHORT, kit.MDB_NAME, kit.MDB_PATH, "usr/install",
)},
},
Commands: map[string]*ice.Command{
@ -26,32 +28,59 @@ func init() {
"download": {Name: "download link", Help: "下载", Hand: func(m *ice.Message, arg ...string) {
name := path.Base(arg[0])
if m.Richs(INSTALL, "", name, func(key string, value map[string]interface{}) {
m.Push(key, value, []string{"time", "progress", "size", "name", "link"})
}) != nil {
if _, e := os.Stat(path.Join(m.Conf(INSTALL, kit.META_PATH), kit.Format(value["name"]))); e == nil {
m.Push(key, value, []string{"time", "progress", "size", "name", "link"})
}
}) != nil && len(m.Appendv("name")) > 0 {
// 查询
return
}
// 进度
m.Cmd(mdb.INSERT, m.Prefix(INSTALL), "", mdb.HASH, kit.MDB_NAME, name, kit.MDB_LINK, arg[0])
m.Richs(INSTALL, "", name, func(key string, value map[string]interface{}) {
m.Optionv("progress", func(size int, total int) {
value["progress"], value["size"], value["total"] = size*100/total, size, total
m.Log_IMPORT(kit.MDB_FILE, name, "per", size*100/total, kit.MDB_SIZE, kit.FmtSize(int64(size)), "total", kit.FmtSize(int64(total)))
})
})
msg := m.Cmd(web.SPIDE, "dev", "cache", http.MethodGet, arg[0])
p := path.Join(m.Conf(INSTALL, "meta.path"), name)
m.Cmdy(nfs.LINK, p, msg.Append("file"))
// 下载
m.Option(cli.CMD_DIR, m.Conf(INSTALL, kit.META_PATH))
if strings.HasPrefix(arg[0], "ftp") {
m.Cmdy(cli.SYSTEM, "wget", arg[0])
} else {
msg := m.Cmd(web.SPIDE, web.SPIDE_DEV, web.SPIDE_CACHE, web.SPIDE_GET, arg[0])
p := path.Join(m.Conf(INSTALL, kit.META_PATH), name)
m.Cmdy(nfs.LINK, p, msg.Append("file"))
}
m.Option(cli.CMD_DIR, m.Conf(INSTALL, "meta.path"))
// 解压
m.Cmd(cli.SYSTEM, "tar", "xvf", name)
m.Echo(p)
}},
"start": {Name: "start source binary", Help: "启动", Hand: func(m *ice.Message, arg ...string) {
port := m.Cmdx(tcp.PORT, "get")
p := path.Join(m.Conf(cli.DAEMON, kit.META_PATH), port)
os.MkdirAll(p, ice.MOD_DIR)
// 复制
m.Cmd(nfs.DIR, path.Join(m.Conf(INSTALL, kit.META_PATH), arg[0])).Table(func(index int, value map[string]string, head []string) {
m.Cmd(cli.SYSTEM, "cp", "-r", strings.TrimSuffix(value[kit.MDB_PATH], "/"), p)
})
// 启动
m.Option(cli.CMD_DIR, p)
m.Cmdy(cli.DAEMON, arg[1])
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Option("fields", "time,progress,size,total,name,link")
if len(arg) > 0 {
// 详情
m.Cmdy(mdb.SELECT, m.Prefix(INSTALL), "", mdb.HASH, kit.MDB_NAME, arg[0])
return
}
// 列表
m.Option("fields", "time,progress,size,total,name,link")
m.Cmdy(mdb.SELECT, m.Prefix(INSTALL), "", mdb.HASH)
m.Sort(kit.MDB_TIME, "time_r")
}},

View File

@ -147,13 +147,13 @@ const (
func init() {
Index.Merge(&ice.Context{
Commands: map[string]*ice.Command{
WEBPACK: {Name: "webpack", Help: "打包", Action: map[string]*ice.Action{
WEBPACK: {Name: "webpack path=auto auto 打包", Help: "打包", Action: map[string]*ice.Action{
"pack": {Name: "pack", Help: "打包", Hand: func(m *ice.Message, arg ...string) {
m.Option(nfs.DIR_ROOT, "usr/volcanos")
m.Option(nfs.DIR_TYPE, nfs.FILE)
m.Option(nfs.DIR_DEEP, "true")
js, _, e := kit.Create("usr/volcanos/cache.js")
js, p, e := kit.Create("usr/volcanos/cache.js")
m.Assert(e)
defer js.Close()
@ -178,8 +178,13 @@ func init() {
js.WriteString(`_can_name = "` + path.Join("/", k) + "\"\n")
js.WriteString(m.Cmdx(nfs.CAT, "usr/volcanos/"+k))
}
m.Echo(p)
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) > 0 {
m.Cmdy(nfs.CAT, path.Join("usr/publish", arg[0]))
return
}
m.Option(nfs.DIR_ROOT, "usr/publish")
m.Option(nfs.DIR_TYPE, nfs.FILE)
m.Option(nfs.DIR_DEEP, "true")

View File

@ -26,6 +26,7 @@ func init() {
}},
"show": {Name: "show name", Help: "渲染", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if file, e := avutil.Open(arg[0]); m.Assert(e) {
defer file.Close()
if streams, e := file.Streams(); m.Assert(e) {
for _, stream := range streams {
if stream.Type().IsAudio() {

View File

@ -20,7 +20,7 @@ func init() {
)},
},
Commands: map[string]*ice.Command{
FEEL: {Name: "feel path=auto 刷新:button=auto 上传:button 上一页:button 下一页:button 参数:button", Help: "影音媒体", Meta: kit.Dict(
FEEL: {Name: "feel path=auto auto 上传:button 上一页:button 下一页:button 参数:button", Help: "影音媒体", Meta: kit.Dict(
"display", "/plugin/local/wiki/feel.js", "detail", []string{"标签", "删除"},
), Action: map[string]*ice.Action{
mdb.CREATE: {Name: "create", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
@ -49,6 +49,7 @@ func init() {
m.Echo(path.Join(m.Conf(FEEL, "meta.path"), arg[0]))
return
}
m.Sort("time", "time_r")
}},
},
}, nil)

View File

@ -10,7 +10,10 @@ import (
var ErrWarn = "warn: "
var ErrNotAuth = "not auth: "
var ErrNotJoin = "not join: "
var ErrNotFound = "not found: "
var ErrNotEnough = "not enough: "
var ErrStart = "err start: "
func (m *Message) log(level string, str string, arg ...interface{}) *Message {
if str = strings.TrimSpace(kit.Format(str, arg...)); Log != nil {

View File

@ -3,56 +3,250 @@ package crx
import (
"github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/mdb"
"github.com/shylinux/icebergs/base/nfs"
"github.com/shylinux/icebergs/base/web"
"github.com/shylinux/icebergs/core/code"
"github.com/shylinux/toolkits"
"encoding/csv"
"github.com/nareix/joy4/av"
"github.com/nareix/joy4/av/avutil"
"io/ioutil"
"os"
"path"
"sort"
)
const CHROME = "chrome"
const HISTORY = "history"
const BOOKMARK = "bookmark"
const (
SPIDED = "spided"
CACHED = "cached"
)
var Index = &ice.Context{Name: "chrome", Help: "浏览器",
Configs: map[string]*ice.Config{
CHROME: {Name: "chrome", Help: "浏览器", Value: kit.Data(
kit.MDB_SHORT, "name", web.FAVOR, "url.history",
kit.MDB_SHORT, "name", "history", "url.history",
)},
SPIDED: {Name: "spided", Help: "网页爬虫", Value: kit.Data(
kit.MDB_SHORT, kit.MDB_LINK, kit.MDB_PATH, "usr/spide",
)},
CACHED: {Name: "spided", Help: "网页爬虫", Value: kit.Data(
kit.MDB_SHORT, kit.MDB_LINK, kit.MDB_PATH, "usr/spide",
)},
},
Commands: map[string]*ice.Command{
"/crx": {Name: "/crx", Help: "/crx", Action: map[string]*ice.Action{
web.HISTORY: {Name: "history", Help: "历史记录", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(web.SPIDE, "dev", "/code/chrome/favor", "cmds", mdb.INSERT,
"tab", m.Conf(CHROME, "meta.favor"), "name", arg[1], "note", arg[2],
"sid", m.Option("sid"))
ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Load()
}},
ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Save(SPIDED, CACHED)
}},
CHROME: {Name: "chrome wid=auto url auto 编译:button 下载:button", Help: "浏览器", Action: map[string]*ice.Action{
"compile": {Name: "compile", Help: "编译", Hand: func(m *ice.Message, arg ...string) {
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Cmdy(web.SPACE, CHROME, CHROME, arg)
}},
SPIDED: {Name: "spided wid=auto tid=auto cmd auto", Help: "网页爬虫", Action: map[string]*ice.Action{
"download": {Name: "download", Help: "下载", Hand: func(m *ice.Message, arg ...string) {
if m.Richs(CACHED, "", m.Option("link"), func(key string, value map[string]interface{}) {
if _, e := os.Stat(path.Join(m.Conf(CACHED, kit.META_PATH), m.Option("name"))); e == nil {
m.Push(key, value)
}
}) != nil && len(m.Appendv("name")) > 0 {
return
}
m.Cmd(mdb.INSERT, m.Prefix(CACHED), "", mdb.HASH,
kit.MDB_LINK, m.Option("link"),
kit.MDB_TYPE, m.Option("type"),
kit.MDB_NAME, m.Option("name"),
kit.MDB_TEXT, m.Option("text"),
)
// 进度
m.Richs(CACHED, "", m.Option("link"), func(key string, value map[string]interface{}) {
m.Optionv("progress", func(size int, total int) {
p := size * 100 / total
if p != value["progress"] {
m.Log_IMPORT(kit.MDB_FILE, m.Option("name"), "per", size*100/total, kit.MDB_SIZE, kit.FmtSize(int64(size)), "total", kit.FmtSize(int64(total)))
}
value["progress"], value["size"], value["total"] = p, size, total
})
})
// 下载
msg := m.Cmd(web.SPIDE, web.SPIDE_DEV, web.SPIDE_CACHE, web.SPIDE_GET, m.Option("link"))
p := path.Join(m.Conf(CACHED, kit.META_PATH), m.Option("name"))
m.Cmdy(nfs.LINK, p, msg.Append("file"))
if file, e := avutil.Open(p); m.Assert(e) {
defer file.Close()
if streams, e := file.Streams(); m.Assert(e) {
for _, stream := range streams {
if stream.Type().IsAudio() {
} else if stream.Type().IsVideo() {
vstream := stream.(av.VideoCodecData)
if vstream.Width() > vstream.Height() {
m.Cmdy(nfs.LINK, path.Join(m.Conf(CACHED, kit.META_PATH), "横屏", m.Option("name")), p)
} else {
m.Cmdy(nfs.LINK, path.Join(m.Conf(CACHED, kit.META_PATH), "竖屏", m.Option("name")), p)
}
}
}
}
}
}},
"compile": {Name: "compile", Help: "编译", Hand: func(m *ice.Message, arg ...string) {
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
msg := m.Cmd(web.SPACE, CHROME, CHROME, arg)
switch kit.Select("spide", arg, 2) {
case "cache":
m.Option("fields", "time,type,progress,size,total,name,text,link")
m.Cmdy(mdb.SELECT, m.Prefix(SPIDED), "", mdb.HASH)
case "spide":
if len(arg) > 1 {
msg.PushAction("下载")
msg.Table(func(index int, value map[string]string, head []string) {
m.Push("time", value["time"])
m.Push("type", value["type"])
m.Push("action", value["action"])
m.Push("name", value["name"])
switch value["type"] {
case "img":
m.Push("text", m.Cmdx(mdb.RENDER, web.RENDER.IMG, value["text"]))
case "video":
m.Push("text", m.Cmdx(mdb.RENDER, web.RENDER.Video, value["text"]))
default:
m.Push("text", value["text"])
}
m.Push("link", value["link"])
})
break
}
fallthrough
default:
m.Copy(msg)
}
}},
CACHED: {Name: "cached hash=auto auto 清理:button 导出:button", Help: "网页爬虫", Action: map[string]*ice.Action{
"download": {Name: "download", Help: "下载", Hand: func(m *ice.Message, arg ...string) {
m.Richs(CACHED, "", m.Option("link"), func(key string, value map[string]interface{}) {
m.Optionv("progress", func(size int, total int) {
value["progress"], value["size"], value["total"] = size*100/total, size, total
m.Log_IMPORT(kit.MDB_FILE, m.Option("name"), "per", size*100/total, kit.MDB_SIZE, kit.FmtSize(int64(size)), "total", kit.FmtSize(int64(total)))
})
})
msg := m.Cmd(web.SPIDE, web.SPIDE_DEV, web.SPIDE_CACHE, web.SPIDE_GET, m.Option("link"))
p := path.Join(m.Conf(CACHED, kit.META_PATH), m.Option("name"))
m.Cmdy(nfs.LINK, p, msg.Append("file"))
// 完成
if file, e := avutil.Open(p); m.Assert(e) {
defer file.Close()
if streams, e := file.Streams(); m.Assert(e) {
for _, stream := range streams {
if stream.Type().IsAudio() {
} else if stream.Type().IsVideo() {
vstream := stream.(av.VideoCodecData)
if vstream.Width() > vstream.Height() {
m.Cmdy(nfs.LINK, path.Join(m.Conf(CACHED, kit.META_PATH), "横屏", m.Option("name")), p)
} else {
m.Cmdy(nfs.LINK, path.Join(m.Conf(CACHED, kit.META_PATH), "竖屏", m.Option("name")), p)
}
}
}
}
}
}},
"prune": {Name: "prune", Help: "清理", Hand: func(m *ice.Message, arg ...string) {
m.Richs(CACHED, "", kit.MDB_FOREACH, func(key string, value map[string]interface{}) {
if kit.Int(value["progress"]) == 100 {
dir := path.Join("var/data", m.Prefix(CACHED), "")
name := path.Join(dir, kit.Keys(key, "json"))
if f, p, e := kit.Create(name); e == nil {
defer f.Close()
// 保存数据
if n, e := f.WriteString(kit.Format(value)); e == nil {
m.Log_EXPORT("file", p, kit.MDB_SIZE, n)
}
}
m.Conf(CACHED, kit.Keys(kit.MDB_HASH, key), "")
}
})
}},
"export": {Name: "export", Help: "导出", Hand: func(m *ice.Message, arg ...string) {
f, p, e := kit.Create(path.Join("usr/export", m.Prefix(CACHED), "list.csv"))
m.Assert(e)
defer f.Close()
w := csv.NewWriter(f)
defer w.Flush()
count := 0
head := []string{}
m.Cmd(nfs.DIR, path.Join("var/data", m.Prefix(CACHED))+"/").Table(func(index int, v map[string]string, h []string) {
f, e := os.Open(v["path"])
m.Assert(e)
defer f.Close()
b, e := ioutil.ReadAll(f)
m.Assert(e)
value, ok := kit.UnMarshal(string(b)).(map[string]interface{})
if !ok {
return
}
if index == 0 {
// 输出表头
for k := range value {
head = append(head, k)
}
sort.Strings(head)
w.Write(head)
}
// 输出数据
data := []string{}
for _, k := range head {
data = append(data, kit.Format(value[k]))
}
w.Write(data)
count++
})
m.Log_EXPORT(kit.MDB_FILE, p, kit.MDB_COUNT, count)
m.Echo(p)
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Option("cache.limit", 100)
m.Option("fields", "time,hash,type,progress,size,total,name,text,link")
m.Cmdy(mdb.SELECT, m.Prefix(CACHED), "", mdb.HASH)
m.Sort("time", "time_r")
m.PushAction("下载")
m.Appendv(ice.MSG_APPEND, "time", "type", "name", "text",
"action", "progress", "size", "total", "hash", "link")
}},
"/crx": {Name: "/crx", Help: "插件", Action: map[string]*ice.Action{
web.HISTORY: {Name: "history", Help: "历史记录", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(web.SPIDE, web.SPIDE_DEV, "/code/chrome/favor", "cmds", mdb.INSERT, "sid", m.Option("sid"),
"tab", m.Conf(CHROME, "meta.history"), "name", arg[1], "note", arg[2])
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
}},
"/favor": {Name: "/favor", Help: "收藏", Action: map[string]*ice.Action{
mdb.INSERT: {Name: "insert", Help: "插入", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(web.FAVOR, mdb.INSERT, m.Option("tab"), web.SPIDE, m.Option("name"), m.Option("note"))
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}},
CHROME: {Name: "chrome name=chrome wid=auto url auto", Help: "浏览器", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 {
// 窗口列表
m.Richs(web.SPACE, nil, kit.MDB_FOREACH, func(key string, value map[string]interface{}) {
if kit.Format(value[kit.MDB_TYPE]) == CHROME {
m.Push(key, value, []string{kit.MDB_TIME, kit.MDB_NAME})
}
})
return
}
// 下发命令
m.Cmdy(web.SPACE, arg[0], CHROME, arg[1:])
}},
BOOKMARK: {Name: "bookmark name=chrome auto", Help: "书签", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 {
// 窗口列表
m.Cmdy(CHROME)
return
}
// 下发命令
m.Cmdy(web.SPACE, arg[0], BOOKMARK, arg[1:])
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
}},
},
}

View File

@ -1,24 +1,21 @@
title "HTML5"
premenu
refer "官网" `
官网 https://www.w3.org/
文档 https://developer.mozilla.org/
源码 https://github.com/chromium/chromium/
插件 chrome://extensions
`
chapter "应用"
field draw web.wiki.draw.draw args hi.svg
field trend web.code.git.trend args icebergs
field spide web.code.git.spide args icebergs
chapter "安装"
field chrome web.code.chrome.chrome
chapter "本地"
chapter "应用"
section "收藏夹"
field favor web.favor args `[ url.history ]`
section "命令行"
refer `
终端 terminal://
博客 https://www.cnblogs.com/lymvv/p/8431238.html
`
field chrome web.code.chrome.chrome
field bookmark web.code.chrome.bookmark
# other "https://www.cnblogs.com/lymvv/p/8431238.html"
# baidu "html"

View File

@ -3,13 +3,10 @@ package es
import (
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/cli"
"github.com/shylinux/icebergs/base/mdb"
"github.com/shylinux/icebergs/base/tcp"
"github.com/shylinux/icebergs/base/web"
"github.com/shylinux/icebergs/core/code"
kit "github.com/shylinux/toolkits"
"os"
"path"
"runtime"
"strings"
@ -20,6 +17,7 @@ const ES = "es"
var Index = &ice.Context{Name: ES, Help: "搜索",
Configs: map[string]*ice.Config{
ES: {Name: ES, Help: "搜索", Value: kit.Data(
"address", "http://localhost:9200",
"windows", "https://elasticsearch.thans.cn/downloads/elasticsearch/elasticsearch-7.3.2-windows-x86_64.zip",
"darwin", "https://elasticsearch.thans.cn/downloads/elasticsearch/elasticsearch-7.3.2-darwin-x86_64.tar.gz",
"linux", "https://elasticsearch.thans.cn/downloads/elasticsearch/elasticsearch-7.3.2-linux-x86_64.tar.gz",
@ -30,91 +28,68 @@ var Index = &ice.Context{Name: ES, Help: "搜索",
ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}},
ES: {Name: "es hash=auto auto 启动:button 安装:button", Help: "搜索", Action: map[string]*ice.Action{
"install": {Name: "install", Help: "安装", Hand: func(m *ice.Message, arg ...string) {
"download": {Name: "download", Help: "安装", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy("web.code.install", "download", m.Conf(ES, kit.Keys(kit.MDB_META, runtime.GOOS)))
}},
"start": {Name: "start", Help: "启动", Hand: func(m *ice.Message, arg ...string) {
name := path.Base(m.Conf(ES, kit.Keys(kit.MDB_META, runtime.GOOS)))
name = strings.Join(strings.Split(name, "-")[:2], "-")
port := m.Cmdx(tcp.PORT, "get")
p := "var/daemon/" + port
os.MkdirAll(p, ice.MOD_DIR)
for _, dir := range []string{"bin", "jdk", "lib", "logs", "config", "modules", "plugins"} {
m.Cmd(cli.SYSTEM, "cp", "-r", "usr/install/"+name+"/"+dir, p)
}
m.Option(cli.CMD_DIR, p)
m.Cmdy(cli.DAEMON, "bin/elasticsearch")
m.Cmdy("web.code.install", "start", name, "bin/elasticsearch")
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 {
m.Cmdy(cli.DAEMON)
m.Cmd(cli.DAEMON).Table(func(index int, value map[string]string, head []string) {
if strings.HasPrefix(value["name"], "bin/elasticsearch") {
m.Push("time", value["time"])
m.Push("hash", value["hash"])
m.Push("status", value["status"])
m.Push("pid", value["pid"])
m.Push("name", value["name"])
m.Push("dir", value["dir"])
}
})
return
}
m.Richs(cli.DAEMON, "", arg[0], func(key string, value map[string]interface{}) {
m.Cmdy("web.spide", "dev", "raw", "GET", "http://localhost:9200")
m.Cmdy(web.SPIDE, web.SPIDE_DEV, web.SPIDE_RAW, web.SPIDE_GET, m.Conf(ES, "meta.address"))
})
}},
"GET": {Name: "GET 查看:button cmd=/", Help: "命令", Action: map[string]*ice.Action{}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if pod := m.Option("_pod"); pod != "" {
m.Option("_pod", "")
m.Cmdy(web.SPACE, pod, "web.code.es.GET", arg)
return
m.Cmdy(web.SPACE, pod, m.Prefix(cmd), arg)
if m.Result(0) != ice.ErrWarn || m.Result(1) != ice.ErrNotFound {
return
}
m.Set(ice.MSG_RESULT)
}
m.Option("header", "Content-Type", "application/json")
m.Echo(kit.Formats(kit.UnMarshal(m.Cmdx("web.spide", "dev", "raw", "GET", kit.MergeURL2("http://localhost:9200", kit.Select("/", arg, 0))))))
m.Option(web.SPIDE_HEADER, web.ContentType, web.ContentJSON)
m.Echo(kit.Formats(kit.UnMarshal(m.Cmdx(web.SPIDE, web.SPIDE_DEV, web.SPIDE_RAW,
web.SPIDE_GET, kit.MergeURL2(m.Conf(ES, "meta.address"), kit.Select("/", arg, 0))))))
}},
"CMD": {Name: "CMD 执行:button method:select=GET|PUT|POST|DELETE cmd=/ data:textarea", Help: "命令", Action: map[string]*ice.Action{}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if pod := m.Option("_pod"); pod != "" {
m.Option("_pod", "")
m.Cmdy(web.SPACE, pod, "web.code.es.CMD", arg)
return
}
m.Cmdy(web.SPACE, pod, m.Prefix(cmd), arg)
if arg[0] == "GET" {
m.Option("header", "Content-Type", "application/json")
m.Echo(kit.Formats(kit.UnMarshal(m.Cmdx("web.spide", "dev", "raw", arg[0], kit.MergeURL2("http://localhost:9200", arg[1])))))
return
}
m.Option("header", "Content-Type", "application/json")
m.Echo(kit.Formats(kit.UnMarshal(m.Cmdx("web.spide", "dev", "raw", arg[0], kit.MergeURL2("http://localhost:9200", arg[1]), "data", arg[2]))))
}},
"index": {Name: "table index 创建:button", Help: "索引", Action: map[string]*ice.Action{}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 {
m.Cmdy(cli.DAEMON)
return
}
m.Option("header", "Content-Type", "application/json")
m.Echo(kit.Formats(kit.UnMarshal(m.Cmdx("web.spide", "dev", "raw", "PUT", "http://localhost:9200/"+arg[0]))))
}},
"mapping": {Name: "mapping index mapping 创建:button text:textarea", Help: "映射", Action: map[string]*ice.Action{}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 {
m.Cmdy(cli.DAEMON)
return
}
m.Option("header", "Content-Type", "application/json")
m.Echo(kit.Formats(kit.UnMarshal(m.Cmdx("web.spide", "dev", "raw", "PUT", "http://localhost:9200/"+arg[0]+"/_mapping/"+arg[1], "data", arg[2]))))
}},
"document": {Name: "table index=index_test mapping=mapping_test id=1 查看:button 添加:button data:textarea", Help: "文档", Action: map[string]*ice.Action{
mdb.INSERT: {Name: "insert", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
if len(arg) > 3 {
m.Option("header", "Content-Type", "application/json")
m.Echo(kit.Formats(kit.UnMarshal(m.Cmdx("web.spide", "dev", "raw", "PUT", "http://localhost:9200/"+arg[0]+"/"+arg[1]+"/"+arg[2], "data", arg[3]))))
if m.Result(0) != ice.ErrWarn || m.Result(1) != ice.ErrNotFound {
return
}
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Option("header", "Content-Type", "application/json")
m.Echo(kit.Formats(kit.UnMarshal(m.Cmdx("web.spide", "dev", "raw", "GET", "http://localhost:9200/"+arg[0]+"/"+arg[1]+"/"+arg[2]))))
m.Set(ice.MSG_RESULT)
}
m.Option(web.SPIDE_HEADER, web.ContentType, web.ContentJSON)
prefix := []string{web.SPIDE, web.SPIDE_DEV, web.SPIDE_RAW, arg[0], kit.MergeURL2(m.Conf(ES, "meta.address"), arg[1])}
if len(arg) > 2 {
prefix = append(prefix, web.SPIDE_DATA, arg[2])
}
m.Echo(kit.Formats(kit.UnMarshal(m.Cmdx(prefix))))
}},
},
}

View File

@ -27,16 +27,14 @@ curl http://localhost:9200
`
# field command web.code.es.command option `{ _pod centos.remote }`
field GET web.code.es.GET style command args `[ /index_test/test_type/1 ]` option `{ _pod centos.remote }`
field "查询数据" web.code.es.GET args `[ /index_test/test_type/1 ]` style command option `{ _pod centos.remote }`
field CMD web.code.es.CMD style command args `[ POST /index_test/test_type/1 ] ` content `{
field "提交数据" web.code.es.CMD args `[ POST /index_test/test_type/1 ] ` content `{
"name": "lisi",
"age" : "12"
}` option `{ _pod centos.remote }`
field es web.code.es.es
field install web.code.install
return
field document web.code.es.document
}` style command option `{ _pod centos.remote }`
section 管理
field "服务管理" web.code.es.es
field "进程管理" cli.daemon
field "下载管理" web.code.install

View File

@ -177,11 +177,15 @@ var Index = &ice.Context{Name: GIT, Help: "代码库",
dels := strings.Split(fs[2], " ")
add = adds[0]
del = dels[0]
} else if adds[1] == "insertions(+)" {
// } else if adds[1] == "insertions(+)" {
} else if strings.Contains(adds[1], "insertion") {
m.Debug("what %v", fs)
add = adds[0]
} else {
m.Debug("what %v", adds[1])
del = adds[0]
}
m.Debug("what %v", fs)
}
if total {
@ -293,16 +297,37 @@ var Index = &ice.Context{Name: GIT, Help: "代码库",
"status": {Name: "status name=auto auto 提交:button", Help: "文件状态", Meta: kit.Dict(
"提交", kit.List(
"_input", "select", "name", "action", "values", []string{"add", "opt"},
"_input", "select", "name", "action", "values", []string{"opt", "add"},
"_input", "text", "name", "text", "value", "some",
),
), Action: map[string]*ice.Action{
"add": {Name: "add", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
if strings.Contains(m.Option("name"), ":\\") {
m.Option(cli.CMD_DIR, m.Option("name"))
} else {
m.Option(cli.CMD_DIR, path.Join("usr", m.Option("name")))
}
m.Cmdy(cli.SYSTEM, "git", "add", m.Option("file"))
}},
"submit": {Name: "submit", Help: "提交", Hand: func(m *ice.Message, arg ...string) {
m.Option(cli.CMD_DIR, path.Join(kit.Select("usr", "", path.IsAbs(m.Option("name"))), m.Option("name")))
m.Cmdy(cli.SYSTEM, "git", "commit", "-am", kit.Select("opt some", strings.Join(arg, " ")))
if strings.Contains(m.Option("name"), ":\\") {
m.Option(cli.CMD_DIR, m.Option("name"))
} else {
m.Option(cli.CMD_DIR, path.Join("usr", m.Option("name")))
}
if arg[0] == "action" {
m.Cmdy(cli.SYSTEM, "git", "commit", "-am", kit.Select("opt some", arg[1]+" "+arg[3]))
} else {
m.Cmdy(cli.SYSTEM, "git", "commit", "-am", kit.Select("opt some", strings.Join(arg, " ")))
}
}},
"push": {Name: "push", Help: "上传", Hand: func(m *ice.Message, arg ...string) {
m.Option(cli.CMD_DIR, path.Join("usr", m.Option("name")))
if strings.Contains(m.Option("name"), ":\\") {
m.Option(cli.CMD_DIR, m.Option("name"))
} else {
m.Option(cli.CMD_DIR, path.Join("usr", m.Option("name")))
}
m.Cmdy(cli.SYSTEM, "git", "push")
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
@ -319,9 +344,23 @@ var Index = &ice.Context{Name: GIT, Help: "代码库",
m.Push("name", kit.Value(value, "meta.name"))
m.Push("tags", vs[0])
m.Push("file", vs[1])
list := []string{}
switch vs[0] {
case "##":
if strings.Contains(vs[1], "ahead") {
list = append(list, m.Cmdx(mdb.RENDER, web.RENDER.Button, "上传"))
}
default:
if strings.Contains(vs[0], "??") {
list = append(list, m.Cmdx(mdb.RENDER, web.RENDER.Button, "添加"))
} else {
list = append(list, m.Cmdx(mdb.RENDER, web.RENDER.Button, "提交"))
}
}
m.Push("action", strings.Join(list, ""))
}
})
m.PushAction("提交", "上传")
m.Sort("name")
}},
"_install": {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {

View File

@ -30,8 +30,7 @@ const (
var _tmux = []string{cli.SYSTEM, TMUX}
var Index = &ice.Context{Name: "tmux", Help: "工作台",
Caches: map[string]*ice.Cache{},
var Index = &ice.Context{Name: TMUX, Help: "工作台",
Configs: map[string]*ice.Config{
SESSION: {Name: "session", Help: "会话", Value: kit.Data(
"format", "#{session_id},#{session_attached},#{session_name},#{session_windows},#{session_height},#{session_width}",
@ -59,10 +58,14 @@ var Index = &ice.Context{Name: "tmux", Help: "工作台",
TEXT: {Name: "text 保存:button 清空:button text:textarea", Help: "文本", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) > 0 && arg[0] != "" {
m.Cmd(_tmux, "set-buffer", arg[0])
m.Cmdy("web.wiki.image", "qrcode", arg[0])
m.Echo("\n")
}
m.Echo(m.Cmdx(_tmux, "show-buffer"))
text := m.Cmdx(_tmux, "show-buffer")
m.Cmdy("web.wiki.image", "qrcode", text)
m.Echo("\n")
m.Echo(text)
m.Echo("\n")
m.Render("")
}},
BUFFER: {Name: "buffer [buffer=auto [value]] auto", Help: "缓存", Action: map[string]*ice.Action{

View File

@ -20,15 +20,142 @@ const VIM = "vim"
const VIMRC = "vimrc"
var Index = &ice.Context{Name: "vim", Help: "编辑器",
Caches: map[string]*ice.Cache{},
Commands: map[string]*ice.Command{
ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Conf(web.FAVOR, "meta.render.vimrc", m.AddCmd(&ice.Command{Name: "render favor id", Help: "渲染引擎", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
value := m.Optionv("value").(map[string]interface{})
switch value["name"] {
case "read", "write", "exec":
p := path.Join(kit.Format(kit.Value(value, "extra.pwd")), kit.Format(kit.Value(value, "extra.buf")))
if strings.HasPrefix(kit.Format(kit.Value(value, "extra.buf")), "/") {
p = path.Join(kit.Format(kit.Value(value, "extra.buf")))
}
f, e := os.Open(p)
m.Assert(e)
defer f.Close()
b, e := ioutil.ReadAll(f)
m.Assert(e)
m.Echo(string(b))
default:
m.Cmdy(cli.SYSTEM, "sed", "-n", fmt.Sprintf("/%s/,/^}$/p", value["text"]), kit.Value(value, "extra.buf"))
}
}}))
m.Cmd(mdb.PLUGIN, mdb.CREATE, VIMRC, VIM, c.Cap(ice.CTX_FOLLOW))
m.Cmd(mdb.RENDER, mdb.CREATE, VIMRC, VIM, c.Cap(ice.CTX_FOLLOW))
m.Cmd(mdb.PLUGIN, mdb.CREATE, VIM, VIM, c.Cap(ice.CTX_FOLLOW))
m.Cmd(mdb.RENDER, mdb.CREATE, VIM, VIM, c.Cap(ice.CTX_FOLLOW))
}},
VIM: {Name: "vim 配置:button 编译:button 下载:button", Help: "vim", Action: map[string]*ice.Action{
"download": {Name: "download", Help: "下载", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(code.INSTALL, "download", m.Conf(VIM, "meta.source"))
}},
"compile": {Name: "compile", Help: "编译", Hand: func(m *ice.Message, arg ...string) {
name := path.Base(strings.TrimSuffix(m.Conf(VIM, "meta.source"), ".tar.bz2"))
name = strings.ReplaceAll(strings.ReplaceAll(name, "-", ""), ".", "")
m.Option(cli.CMD_DIR, path.Join(m.Conf(code.INSTALL, kit.META_PATH), name))
m.Cmdy(cli.SYSTEM, "./configure", "--prefix="+kit.Path(m.Conf(VIM, "meta.target")),
"--enable-multibyte=yes", m.Confv(VIM, "meta.config"))
m.Cmdy(cli.SYSTEM, "make", "-j4")
m.Cmdy(cli.SYSTEM, "make", "install")
}},
"prepare": {Name: "prepare", Help: "配置", Hand: func(m *ice.Message, arg ...string) {
// 语法脚本
for _, s := range []string{"go.vim", "shy.vim", "javascript.vim"} {
m.Cmd(nfs.LINK, path.Join(os.Getenv("HOME"), ".vim/syntax/"+s), "etc/conf/"+s)
}
// 启动脚本
m.Cmd(nfs.LINK, path.Join(os.Getenv("HOME"), ".vim/autoload/plug.vim"), "etc/conf/plug.vim")
m.Cmd(nfs.LINK, path.Join(os.Getenv("HOME"), ".vimrc"), "etc/conf/vimrc")
// 安装插件
m.Echo("vim -c PlugInstall\n")
m.Echo("vim -c GoInstallBinaries\n")
}},
mdb.PLUGIN: {Hand: func(m *ice.Message, arg ...string) {
m.Echo(m.Conf(VIM, "meta.plug"))
}},
mdb.RENDER: {Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(nfs.CAT, path.Join(arg[2], arg[1]))
}},
}},
"/sync": {Name: "/sync", Help: "同步", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Render(ice.RENDER_RESULT)
switch arg[0] {
case "read", "write", "exec", "insert":
m.Cmd(web.FAVOR, m.Conf(VIM, "meta.history"), web.TYPE_VIMRC, arg[0], kit.Select(m.Option("arg"), m.Option("sub")),
"pwd", m.Option("pwd"), "buf", m.Option("buf"), "row", m.Option("row"), "col", m.Option("col"))
case "trans":
if m.Cmdy(kit.Split(m.Option("arg"))); m.Result() == "" {
m.Table()
}
}
}},
"/input": {Name: "/input", Help: "补全", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Render(ice.RENDER_RESULT)
arg[0] = strings.TrimSpace(arg[0])
if strings.HasPrefix(arg[0], "ice ") {
list := kit.Split(strings.TrimSpace(arg[0]))
switch list[1] {
case "add":
// ice add person 想你 shwq
m.Cmd("web.code.input.push", list[2:])
arg[0] = list[4]
default:
// ice command
if m.Cmdy(list[1:]); m.Result() == "" {
m.Echo("%s\n", arg[0])
m.Table()
}
return
}
}
// 词汇列表
m.Cmd("web.code.input.find", arg[0]).Table(func(index int, value map[string]string, head []string) {
m.Echo("%s\n", value["text"])
})
}},
"/favor": {Name: "/favor", Help: "收藏", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Render(ice.RENDER_RESULT)
if m.Options("arg") {
// 添加收藏
m.Cmdy(web.FAVOR, kit.Select(m.Conf("vim", "meta.history"), m.Option("tab")),
web.TYPE_VIMRC, m.Option("note"), m.Option("arg"),
"pwd", m.Option("pwd"), "buf", m.Option("buf"), "row", m.Option("row"), "col", m.Option("col"))
return
}
// 查看收藏
m.Richs(web.FAVOR, nil, m.Option("tab"), func(key string, val map[string]interface{}) {
m.Grows(web.FAVOR, kit.Keys(kit.MDB_HASH, key), "", "", func(index int, value map[string]interface{}) {
extra := value["extra"].(map[string]interface{})
switch value[kit.MDB_TYPE] {
case web.TYPE_VIMRC:
m.Echo("%v\n", m.Option("tab")).Echo("%v:%v:%v:(%v): %v\n",
extra["buf"], extra["row"], extra["col"], value["name"], value["text"])
}
})
})
}},
},
Configs: map[string]*ice.Config{
VIM: {Name: "vim", Help: "编辑器", Value: kit.Data(
"source", "ftp://ftp.vim.org/pub/vim/unix/vim-8.1.tar.bz2",
"target", "usr/local", "version", "vim81", "config", []interface{}{
"target", "usr/local", "config", []interface{}{
"--enable-pythoninterp=yes",
"--enable-luainterp=yes",
"--enable-cscope=yes",
}, "history", "vim.history",
},
"history", "vim.history",
"plug", kit.Dict(
"split", kit.Dict(
"space", " \t",
@ -83,137 +210,6 @@ var Index = &ice.Context{Name: "vim", Help: "编辑器",
),
)},
},
Commands: map[string]*ice.Command{
ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Conf(web.FAVOR, "meta.render.vimrc", m.AddCmd(&ice.Command{Name: "render favor id", Help: "渲染引擎", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
value := m.Optionv("value").(map[string]interface{})
switch value["name"] {
case "read", "write", "exec":
p := path.Join(kit.Format(kit.Value(value, "extra.pwd")), kit.Format(kit.Value(value, "extra.buf")))
if strings.HasPrefix(kit.Format(kit.Value(value, "extra.buf")), "/") {
p = path.Join(kit.Format(kit.Value(value, "extra.buf")))
}
f, e := os.Open(p)
m.Assert(e)
defer f.Close()
b, e := ioutil.ReadAll(f)
m.Assert(e)
m.Echo(string(b))
default:
m.Cmdy(cli.SYSTEM, "sed", "-n", fmt.Sprintf("/%s/,/^}$/p", value["text"]), kit.Value(value, "extra.buf"))
}
}}))
m.Cmd(mdb.PLUGIN, mdb.CREATE, VIMRC, VIM, c.Cap(ice.CTX_FOLLOW))
m.Cmd(mdb.RENDER, mdb.CREATE, VIMRC, VIM, c.Cap(ice.CTX_FOLLOW))
m.Cmd(mdb.PLUGIN, mdb.CREATE, VIM, VIM, c.Cap(ice.CTX_FOLLOW))
m.Cmd(mdb.RENDER, mdb.CREATE, VIM, VIM, c.Cap(ice.CTX_FOLLOW))
}},
VIM: {Name: VIM, Help: "vim", Action: map[string]*ice.Action{
mdb.PLUGIN: {Hand: func(m *ice.Message, arg ...string) {
m.Echo(m.Conf(VIM, "meta.plug"))
}},
mdb.RENDER: {Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(nfs.CAT, path.Join(arg[2], arg[1]))
}},
}},
"_install": {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
p := path.Join(m.Conf("install", "meta.path"), m.Conf("vim", "meta.version"))
if _, e := os.Stat(p); e != nil {
// 下载源码
m.Option("cmd_dir", m.Conf("install", "meta.path"))
m.Cmd(cli.SYSTEM, "wget", "-O", "vim.tar.gz", m.Conf("vim", "meta.source"))
m.Cmd(cli.SYSTEM, "tar", "xvf", "vim.tar.gz")
}
// 配置选项
m.Option("cmd_dir", p)
m.Cmdy(cli.SYSTEM, "./configure", "--prefix="+kit.Path(m.Conf("vim", "meta.target")),
"--enable-multibyte=yes", m.Confv("vim", "meta.config"))
// 编译安装
m.Cmdy(cli.SYSTEM, "make", "-j4")
m.Cmdy(cli.SYSTEM, "make", "install")
}},
code.PREPARE: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
// 语法脚本
for _, s := range []string{"go.vim", "shy.vim", "javascript.vim"} {
m.Cmd("nfs.link", path.Join(os.Getenv("HOME"), ".vim/syntax/"+s), "etc/conf/"+s)
}
// 启动脚本
m.Cmd("nfs.link", path.Join(os.Getenv("HOME"), ".vim/autoload/plug.vim"), "etc/conf/plug.vim")
m.Cmd("nfs.link", path.Join(os.Getenv("HOME"), ".vimrc"), "etc/conf/vimrc")
// 安装插件
m.Echo("vim -c PlugInstall\n")
m.Echo("vim -c GoInstallBinaries\n")
}},
code.PROJECT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
}},
"/sync": {Name: "/sync", Help: "同步", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Render(ice.RENDER_RESULT)
switch arg[0] {
case "read", "write", "exec", "insert":
m.Cmd(web.FAVOR, m.Conf(VIM, "meta.history"), web.TYPE_VIMRC, arg[0], kit.Select(m.Option("arg"), m.Option("sub")),
"pwd", m.Option("pwd"), "buf", m.Option("buf"), "row", m.Option("row"), "col", m.Option("col"))
case "trans":
if m.Cmdy(kit.Split(m.Option("arg"))); m.Result() == "" {
m.Table()
}
}
}},
"/input": {Name: "/input", Help: "补全", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Render(ice.RENDER_RESULT)
arg[0] = strings.TrimSpace(arg[0])
if strings.HasPrefix(arg[0], "ice ") {
list := kit.Split(strings.TrimSpace(arg[0]))
switch list[1] {
case "add":
// 添加词汇
m.Cmd("web.code.input.push", list[2:])
arg[0] = list[4]
default:
// ice add person 想你 shwq
if m.Cmdy(list[1:]); m.Result() == "" {
m.Echo("%s\n", arg[0])
m.Table()
}
return
}
}
// 词汇列表
m.Cmd("web.code.input.find", arg[0]).Table(func(index int, value map[string]string, head []string) {
m.Echo("%s\n", value["text"])
})
}},
"/favor": {Name: "/favor", Help: "收藏", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Render(ice.RENDER_RESULT)
if m.Options("arg") {
// 添加收藏
m.Cmdy(web.FAVOR, kit.Select(m.Conf("vim", "meta.history"), m.Option("tab")),
web.TYPE_VIMRC, m.Option("note"), m.Option("arg"),
"pwd", m.Option("pwd"), "buf", m.Option("buf"), "row", m.Option("row"), "col", m.Option("col"))
return
}
// 查看收藏
m.Richs(web.FAVOR, nil, m.Option("tab"), func(key string, val map[string]interface{}) {
m.Grows(web.FAVOR, kit.Keys(kit.MDB_HASH, key), "", "", func(index int, value map[string]interface{}) {
extra := value["extra"].(map[string]interface{})
switch value[kit.MDB_TYPE] {
case web.TYPE_VIMRC:
m.Echo("%v\n", m.Option("tab")).Echo("%v:%v:%v:(%v): %v\n",
extra["buf"], extra["row"], extra["col"], value["name"], value["text"])
}
})
})
}},
},
}
func init() { code.Index.Register(Index, &web.Frame{}) }

View File

@ -1,25 +1,60 @@
title "vim"
premenu
refer "官网" `
官网 https://www.vim.org
源码 https://github.com/vim/vim
文档 http://vimdoc.sourceforge.net/htmldoc/usr_toc.html
`
chapter "应用"
chapter "安装"
section "下载源码"
refer `
下载 ftp://ftp.vim.org/pub/vim/unix/vim-8.1.tar.bz2
`
chapter "操作"
section "编译安装"
spark shell `
tar xvf vim-81.tar.bz2 && cd vim81
./configure --prefix=/usr/local --enable-multibyte=yes
make -j4
make install
`
section "使用体验"
spark shell `
vim
`
section "项目"
field "安装" web.code.vim.vim
field "源码" web.code.inner args `[ usr/install/vim81/ src/main.c 110 ]`
field "脚本" web.code.inner args `[ usr/local/share/vim/vim81/ filetype.vim ]`
field "文档" web.code.inner args `[ usr/local/share/vim/vim81/doc/ help.txt ]`
chapter "使用"
chapter "配置"
field "启动配置" web.code.inner args `[ etc/conf/ vimrc ]`
refer `
启动脚本 https://github.com/shylinux/contexts/blob/master/etc/conf/vimrc
`
field "启动脚本" web.code.inner args `[ etc/conf/ vimrc ]`
chapter "插件"
refer `
插件管理器 https://github.com/junegunn/vim-plug
`
field "插件管理器" web.code.inner args `[ etc/conf/ plug.vim ]`
section "状态栏"
refer `
插件管理器 https://github.com/vim-airline/vim-airline
插件 https://github.com/vim-airline/vim-airline
`
chapter "应用"
section "收藏夹"
field favor web.favor args `[ vim.history ]`
section "输入法"
# field input web.code.input.find `[ shwq ]`