From 07165a195752dfc209f7fb22e0ddf8ac20305ce4 Mon Sep 17 00:00:00 2001 From: shylinux Date: Sat, 25 Aug 2018 12:07:09 +0800 Subject: [PATCH] vps add web/wiki --- Makefile | 1 + src/contexts/aaa/aaa.go | 2 +- src/contexts/cli/cli.go | 2 +- src/contexts/ctx.go | 11 +- src/contexts/nfs/nfs.go | 3 +- src/contexts/web/web.go | 191 +++++++++++++++++++++++++++-- src/contexts/yac/yac.go | 36 ++++-- usr/template/common/base.html | 12 ++ usr/template/common/wiki.html | 223 +++++++++++++++++++++++++++++++++- 9 files changed, 450 insertions(+), 31 deletions(-) diff --git a/Makefile b/Makefile index e93c9eff..6cb5cb70 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,7 @@ install: @go get github.com/go-sql-driver/mysql @go get github.com/nsf/termbox-go @go get github.com/skip2/go-qrcode + @go get github.com/gomarkdown/markdown @cp etc/go.snippets ~/.vim/snippets/ @cp etc/shy.vim ~/.vim/syntax/ @touch etc/local.shy diff --git a/src/contexts/aaa/aaa.go b/src/contexts/aaa/aaa.go index f3d5c9d4..c550576d 100644 --- a/src/contexts/aaa/aaa.go +++ b/src/contexts/aaa/aaa.go @@ -169,7 +169,7 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", Help: "用户登录, sessid: 会话ID, username: 用户名, password: 密码, load: 加载用户信息, save: 保存用户信息, filename: 文件名", Form: map[string]int{"cert": 1, "pub": 1, "key": 1, "ip": 1}, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if aaa, ok := m.Target().Server.(*AAA); m.Assert(ok) { // {{{ + if aaa, ok := c.Server.(*AAA); m.Assert(ok) { // {{{ stream := "" if m.Has("ip") { stream = m.Option("ip") diff --git a/src/contexts/cli/cli.go b/src/contexts/cli/cli.go index 63903f60..5517ca0b 100644 --- a/src/contexts/cli/cli.go +++ b/src/contexts/cli/cli.go @@ -168,7 +168,7 @@ func (cli *CLI) Start(m *ctx.Message, arg ...string) bool { // {{{ } m.Optionv("ps_target", cli.target) return nil - }, "parse", arg[1]).Target().Name) + }, "scan", arg[1]).Target().Name) if m.Options("init.shy") { msg := m.Spawn().Cmd("source", m.Conf("init.shy")) diff --git a/src/contexts/ctx.go b/src/contexts/ctx.go index a67ca883..c99ca7d8 100644 --- a/src/contexts/ctx.go +++ b/src/contexts/ctx.go @@ -544,7 +544,7 @@ func (m *Message) Copy(msg *Message, meta string, arg ...string) *Message { // { func (m *Message) Log(action string, str string, arg ...interface{}) *Message { // {{{ l := m.Sess("log", !m.Confs("compact_log")) - if l == nil || m.Detail(0) == "log" || m.Detail(0) == "write" { + if l == nil || m.Detail(0) == "log" || m.Detail(0) == "write" || m.Options("silent") { return m } @@ -973,7 +973,10 @@ func (m *Message) Gets(key string) bool { // {{{ // }}} func (m *Message) Echo(str string, arg ...interface{}) *Message { // {{{ - return m.Add("result", fmt.Sprintf(str, arg...)) + if len(arg) > 0 { + return m.Add("result", fmt.Sprintf(str, arg...)) + } + return m.Add("result", str) } // }}} @@ -2232,8 +2235,8 @@ var CGI = template.FuncMap{ } list := make([]int, n) - for i := 0; i < n; i++ { - list[i] = i + for i := 1; i <= n; i++ { + list[i-1] = i } return list }, // }}} diff --git a/src/contexts/nfs/nfs.go b/src/contexts/nfs/nfs.go index 05389f42..fa5d2b7e 100644 --- a/src/contexts/nfs/nfs.go +++ b/src/contexts/nfs/nfs.go @@ -1209,8 +1209,9 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心", key := m.Meta["append"][i] switch key { case "filename": - if trip > 0 { + if line > -1 && trip > 0 && trip <= len(v) { v = v[trip:] + m.Meta["filename"][line] = v } case "dir": continue diff --git a/src/contexts/web/web.go b/src/contexts/web/web.go index fa9e1fb0..d0180979 100644 --- a/src/contexts/web/web.go +++ b/src/contexts/web/web.go @@ -1,7 +1,10 @@ package web // {{{ // }}} import ( // {{{ + "bufio" "contexts" + "github.com/gomarkdown/markdown" + "path/filepath" "runtime" "encoding/json" @@ -13,7 +16,6 @@ import ( // {{{ "bytes" "mime/multipart" - "path/filepath" "fmt" "io" @@ -101,7 +103,7 @@ func (web *WEB) Trans(m *ctx.Message, key string, hand func(*ctx.Message, *ctx.C msg.Log("cmd", "%s [] %v", key, msg.Meta["option"]) msg.Put("option", "request", r).Put("option", "response", w) - hand(msg, msg.Target(), key) + hand(msg, msg.Target(), msg.Option("path")) switch { case msg.Has("redirect"): @@ -243,6 +245,17 @@ func (web *WEB) Start(m *ctx.Message, arg ...string) bool { // {{{ web.Configs["logheaders"] = &ctx.Config{Name: "日志输出报文头(yes/no)", Value: "no", Help: "日志输出报文头"} m.Capi("nserve", 1) + yac := m.Sess("tags", m.Sess("yac").Cmd("scan")) + yac.Cmd("train", "void", "void", "[\t ]+") + yac.Cmd("train", "other", "other", "[^\n]+") + yac.Cmd("train", "key", "key", "[A-Za-z_][A-Za-z_0-9]*") + yac.Cmd("train", "code", "struct", "struct", "key", "\\{") + yac.Cmd("train", "code", "struct", "\\}", "key", ";") + yac.Cmd("train", "code", "struct", "typedef", "struct", "key", "key", ";") + yac.Cmd("train", "code", "function", "key", "\\*", "key", "(", "other") + yac.Cmd("train", "code", "function", "key", "key", "(", "other") + yac.Cmd("train", "code", "define", "#define", "key", "other") + if m.Cap("protocol") == "https" { web.Caches["cert"] = &ctx.Cache{Name: "服务证书", Value: m.Conf("cert"), Help: "服务证书"} web.Caches["key"] = &ctx.Cache{Name: "服务密钥", Value: m.Conf("key"), Help: "服务密钥"} @@ -277,9 +290,25 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", "cmd": &ctx.Config{Name: "cmd", Value: "tmux", Help: "路由数量"}, "cert": &ctx.Config{Name: "cert", Value: "etc/cert.pem", Help: "路由数量"}, "key": &ctx.Config{Name: "key", Value: "etc/key.pem", Help: "路由数量"}, + "wiki_dir": &ctx.Config{Name: "wiki_dir", Value: "usr/wiki", Help: "路由数量"}, + "which": &ctx.Config{Name: "which", Value: "redis.note", Help: "路由数量"}, "root_index": &ctx.Config{Name: "root_index(true/false)", Value: "true", Help: "路由数量"}, "auto_create": &ctx.Config{Name: "auto_create(true/false)", Value: "true", Help: "路由数量"}, "refresh_time": &ctx.Config{Name: "refresh_time(ms)", Value: "1000", Help: "路由数量"}, + "define": &ctx.Config{Name: "define", Value: map[string]interface{}{ + "ngx_command_t": map[string]interface{}{ + "position": map[string]interface{}{ + "file": "nginx-1.15.2/src/core/ngx_core.h", + "line": "22", + }, + }, + "ngx_command_s": map[string]interface{}{ + "position": map[string]interface{}{ + "file": "nginx-1.15.2/src/core/ngx_conf_file.h", + "line": "77", + }, + }, + }, Help: "路由数量"}, "check": &ctx.Config{Name: "check", Value: map[string]interface{}{ "login": []interface{}{ map[string]interface{}{ @@ -438,9 +467,11 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", "template": "wiki_menu", "title": "wiki_menu", }, map[string]interface{}{ + "module": "web", "command": "/wiki_list", "template": "wiki_list", "title": "wiki_list", }, map[string]interface{}{ + "module": "web", "command": "/wiki_body", "template": "wiki_body", "title": "wiki_body", }, }, @@ -875,11 +906,11 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", // }}} }}, "/create": &ctx.Command{Name: "/create", Help: "创建目录或文件", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - // if check := m.Spawn().Cmd("/share", "/upload", "dir", m.Option("dir")); !check.Results(0) { // {{{ - // m.Copy(check, "append") - // return - // } - // + if check := m.Spawn().Cmd("/share", "/upload", "dir", m.Option("dir")); !check.Results(0) { // {{{ + m.Copy(check, "append") + return + } + r := m.Optionv("request").(*http.Request) if m.Option("method") == "POST" { if m.Options("filename") { //添加文件或目录 @@ -1076,7 +1107,6 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", continue } val := v.(map[string]interface{}) - m.Log("fuck", "why %v", val) //命令模板 if detail, ok := val["detail"].([]interface{}); ok { msg := m.Spawn().Add("detail", detail[0].(string), detail[1:]) @@ -1148,7 +1178,150 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", m.Echo("blog service") }}, - "/wiki": &ctx.Command{Name: "/wiki", Help: "维基", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + "/wiki_tags": &ctx.Command{Name: "/wiki_tags ", Help: "博客", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + if len(arg) > 0 { + m.Option("dir", arg[0]) + } + + yac := m.Find("yac.parse4", true) + + msg := m.Sess("nfs").Cmd("dir", path.Join(m.Conf("wiki_dir"), m.Option("dir")), "dir_name", "path") + for i, v := range msg.Meta["filename"] { + name := strings.TrimSpace(v) + es := strings.Split(name, ".") + switch es[len(es)-1] { + case "pyc", "o", "gz", "tar": + continue + case "c": + m.Log("fuck", "parse %s", name) + case "h": + default: + continue + } + + f, e := os.Open(name) + m.Assert(e) + defer f.Close() + + m.Log("fuck", "parse %d/%d %s", i, len(msg.Meta["filename"]), name) + + bio := bufio.NewScanner(f) + for line := 1; bio.Scan(); line++ { + yac.Options("silent", true) + l := yac.Cmd("parse", "code", "void", bio.Text()) + + key := "" + switch l.Result(1) { + case "struct": + switch l.Result(2) { + case "struct", "}": + key = l.Result(3) + case "typedef": + if l.Result(3) == "struct" { + key = l.Result(5) + } + } + case "function": + switch l.Result(3) { + case "*": + key = l.Result(4) + default: + key = l.Result(3) + } + case "define": + key = l.Result(3) + } + if key != "" { + m.Confv("define", strings.Join([]string{key, "position"}, "."), map[string]interface{}{ + "file": strings.TrimPrefix(name, m.Confx("wiki_dir")), + "line": line, + "type": l.Result(1), + }) + } + + yac.Meta = nil + } + } + m.Log("fuck", "parse %s", time.Now().Format("2006-01-02 15:04:05")) + }}, + "/wiki_body": &ctx.Command{Name: "/wiki_body", Help: "维基", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + if ls, e := ioutil.ReadFile(path.Join(m.Conf("wiki_dir"), m.Confx("which"))); e == nil { + pre := false + es := strings.Split(m.Confx("which"), ".") + if len(es) > 0 { + switch es[len(es)-1] { + case "md": + ls = markdown.ToHTML(ls, nil, nil) + default: + pre = true + } + } + + if pre { + m.Option("nline", bytes.Count(ls, []byte("\n"))) + m.Option("nbyte", len(ls)) + m.Add("append", "code", string(ls)) + m.Add("append", "body", "") + } else { + m.Add("append", "body", string(ls)) + m.Add("append", "code", "") + } + return + } + + if m.Options("query") { + if v, ok := m.Confv("define", m.Option("query")).(map[string]interface{}); ok { + if val, ok := v["position"].(map[string]interface{}); ok { + m.Add("append", "name", fmt.Sprintf("%v#hash_%v", val["file"], val["line"])) + return + } + } + msg := m.Sess("nfs").Cmd("dir", path.Join(m.Conf("wiki_dir"), m.Option("dir")), "dir_name", "path") + for _, v := range msg.Meta["filename"] { + name := strings.TrimPrefix(strings.TrimSpace(v), m.Conf("wiki_dir")) + es := strings.Split(name, ".") + switch es[len(es)-1] { + case "pyc", "o", "gz", "tar": + continue + } + if strings.Contains(name, m.Option("query")) { + m.Add("append", "name", name) + } + } + return + } + + msg := m.Spawn().Cmd("/wiki_list") + m.Copy(msg, "append").Copy(msg, "option") + }}, + "/wiki_list": &ctx.Command{Name: "/wiki_list", Help: "维基", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + ls, e := ioutil.ReadDir(path.Join(m.Conf("wiki_dir"), m.Option("which"))) + m.Option("dir", m.Option("which")) + if e != nil { + dir, _ := path.Split(m.Option("which")) + m.Option("dir", dir) + ls, e = ioutil.ReadDir(path.Join(m.Conf("wiki_dir"), dir)) + } + + parent, _ := path.Split(strings.TrimSuffix(m.Option("dir"), "/")) + m.Option("parent", parent) + for _, l := range ls { + if l.Name()[0] == '.' { + continue + } + es := strings.Split(l.Name(), ".") + if len(es) > 0 { + switch es[len(es)-1] { + case "pyc", "o", "gz", "tar": + continue + } + } + + m.Add("append", "name", l.Name()) + } + }}, + "/wiki/": &ctx.Command{Name: "/wiki", Help: "维基", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + m.Option("which", strings.TrimPrefix(key, "/wiki/")) m.Append("template", "wiki") }}, "temp": &ctx.Command{Name: "temp", Help: "应用示例", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { diff --git a/src/contexts/yac/yac.go b/src/contexts/yac/yac.go index 874d5dde..0c03836e 100644 --- a/src/contexts/yac/yac.go +++ b/src/contexts/yac/yac.go @@ -185,7 +185,7 @@ func (yac *YAC) train(m *ctx.Message, page, hash int, word []string) (int, []*Po } // }}} -func (yac *YAC) parse(m *ctx.Message, out *ctx.Message, page int, void int, line string, level int) (string, []string) { // {{{ +func (yac *YAC) parse(m *ctx.Message, out *ctx.Message, page int, void int, line string, level int) (string, []string, int) { // {{{ if m.Confs("debug") { m.Log("debug", "%s\\%d %s(%d): %s", m.Conf("label")[0:level], level, yac.name(page), page, line) } @@ -224,7 +224,7 @@ func (yac *YAC) parse(m *ctx.Message, out *ctx.Message, page int, void int, line if state == nil { //嵌套语法递归解析 for i := 0; i < m.Capi("ncell"); i++ { if x := yac.mat[s][byte(i)]; i < m.Capi("nlang") && x != nil { - if l, w := yac.parse(m, out, i, void, line, level+1); l != line { + if l, w, _ := yac.parse(m, out, i, void, line, level+1); l != line { line, word = l, append(word, w...) state = x break @@ -245,7 +245,7 @@ func (yac *YAC) parse(m *ctx.Message, out *ctx.Message, page int, void int, line if hash == 0 { word = word[:0] - } else { //执行命令 + } else if out != nil { //执行命令 msg := out.Spawn(m.Source()).Add("detail", yac.hand[hash], word) if m.Back(msg); msg.Hand { //命令替换 m.Assert(!msg.Has("return")) @@ -257,7 +257,7 @@ func (yac *YAC) parse(m *ctx.Message, out *ctx.Message, page int, void int, line m.Log("debug", "%s/%d %s(%d): %v", m.Conf("label")[0:level], level, yac.name(page), page, word) } - return line, word + return line, word, hash } // }}} @@ -266,7 +266,7 @@ func (yac *YAC) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server c.Caches = map[string]*ctx.Cache{} c.Configs = map[string]*ctx.Config{} - if len(arg) > 0 && arg[0] == "parse" { + if len(arg) > 0 && arg[0] == "scan" { return yac } @@ -277,7 +277,7 @@ func (yac *YAC) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server // }}} func (yac *YAC) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{ - if len(arg) > 0 && arg[0] == "parse" { + if len(arg) > 0 && arg[0] == "scan" { return yac } @@ -304,7 +304,7 @@ func (yac *YAC) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{ // }}} func (yac *YAC) Start(m *ctx.Message, arg ...string) (close bool) { // {{{ - if len(arg) > 0 && arg[0] == "parse" { + if len(arg) > 0 && arg[0] == "scan" { lex := m.Sess("lex") if lex.Cap("status") != "start" { lex.Target().Start(lex) @@ -338,7 +338,7 @@ func (yac *YAC) Start(m *ctx.Message, arg ...string) (close bool) { // {{{ if len(line) == 0 { continue } - _, word := yac.parse(m, out, m.Optioni("page"), m.Optioni("void"), line, 1) + _, word, _ := yac.parse(m, out, m.Optioni("page"), m.Optioni("void"), line, 1) if len(word) > 0 { word = word[:len(word)-1] @@ -469,14 +469,28 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心", } // }}} }}, - "parse": &ctx.Command{ - Name: "parse filename [yac_name [help]] [line line] [void void]", + "parse": &ctx.Command{Name: "parse page hash word...", Help: "添加语法规则, page: 语法集合, hash: 语句类型, word: 语法模板", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + if yac, ok := m.Target().Server.(*YAC); m.Assert(ok) { // {{{ + m.Optioni("page", yac.page[arg[0]]) + m.Optioni("void", yac.page[arg[1]]) + + str, word, hash := yac.parse(m, nil, m.Optioni("page"), m.Optioni("void"), arg[2], 1) + m.Result(str, yac.hand[hash], word) + } + // }}} + }}, + "scan": &ctx.Command{ + Name: "scan filename [yac_name [help]] [line line] [void void]", Help: "解析文件, filename: yac_name:模块名, yac_help:模块帮助, 文件名, line: 默认语法, void: 默认空白", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { if yac, ok := m.Target().Server.(*YAC); m.Assert(ok) { // {{{ m.Optioni("page", yac.page["line"]) m.Optioni("void", yac.page["void"]) - m.Start(m.Confx("yac_name", arg, 1), m.Confx("yac_help", arg, 2), key, arg[0]) + if len(arg) > 0 { + m.Start(m.Confx("yac_name", arg, 1), m.Confx("yac_help", arg, 2), key, arg[0]) + } else { + m.Start(m.Confx("yac_name", arg, 1), m.Confx("yac_help", arg, 2)) + } } // }}} }}, diff --git a/usr/template/common/base.html b/usr/template/common/base.html index e9df672f..c95defb3 100644 --- a/usr/template/common/base.html +++ b/usr/template/common/base.html @@ -2,6 +2,7 @@ + {{option .Meta "page_title"}} + +
+
+
+
+ +
Q
+
+
shylinux
+
+
+ {{$msg := .}} + {{$ncol := append . |len}} + {{$nrow := append . 0|append .|len}} +
    +
  • +
    返回上一层
    +
  • + {{range $row, $val := append . 0|append .}} +
  • +
    + {{append $msg "name" $row}} +
    +
  • + {{end}} +
+
{{end}} + {{define "wiki_body"}} -
hello wiki world!
+ + +
+
+
+
+ {{range option . "nline"|meta|list}} +
{{.}}
+ {{end}} +
+ {{$msg := .}} + {{if append . "name"}} +
    + {{range append . "name"}} + + {{end}} +
      + {{else}} +

      {{append . "body"|meta|unscaped}}

      +

      {{append . "code"|meta}}

      + {{end}} +

+
+
{{end}}