diff --git a/src/contexts/ctx.go b/src/contexts/ctx.go
index 3b8afeb3..190d7a3f 100644
--- a/src/contexts/ctx.go
+++ b/src/contexts/ctx.go
@@ -98,6 +98,11 @@ func Chain(m *Message, data interface{}, args ...interface{}) interface{} { // {
}
i = -2
continue
+ case []interface{}:
+ keys = []string{}
+ for _, v := range arg {
+ keys = append(keys, fmt.Sprintf("%v", v))
+ }
case []string:
keys = arg
keys = strings.Split(strings.Join(arg, "."), ".")
diff --git a/src/contexts/web/web.go b/src/contexts/web/web.go
index 53d20aff..bcc13006 100644
--- a/src/contexts/web/web.go
+++ b/src/contexts/web/web.go
@@ -91,35 +91,67 @@ func (web *WEB) Merge(m *ctx.Message, uri string, arg ...string) string { // {{{
func (web *WEB) Trans(m *ctx.Message, key string, hand func(*ctx.Message, *ctx.Context, string, ...string)) { // {{{
web.HandleFunc(key, func(w http.ResponseWriter, r *http.Request) {
msg := m.Spawn()
- msg.Option("method", r.Method)
- msg.Option("path", r.URL.Path)
- msg.Option("referer", r.Header.Get("Referer"))
+ msg.TryCatch(msg, true, func(msg *ctx.Message) {
+ msg.Option("method", r.Method)
+ msg.Option("path", r.URL.Path)
+ msg.Option("referer", r.Header.Get("Referer"))
- for _, v := range r.Cookies() {
- msg.Option(v.Name, v.Value)
- }
- for k, v := range r.Form {
- msg.Add("option", k, v)
- }
-
- msg.Log("cmd", "%s [] %v", key, msg.Meta["option"])
- msg.Put("option", "request", r).Put("option", "response", w)
- hand(msg, msg.Target(), msg.Option("path"))
-
- switch {
- case msg.Has("directory"):
- http.ServeFile(w, r, msg.Append("directory"))
- case msg.Has("redirect"):
- http.Redirect(w, r, msg.Append("redirect"), http.StatusFound)
- case msg.Has("template"):
- msg.Spawn().Cmd("/render", msg.Meta["template"])
- case msg.Has("append"):
- msg.Spawn().Copy(msg, "result").Copy(msg, "append").Cmd("/json")
- default:
- for _, v := range msg.Meta["result"] {
- w.Write([]byte(v))
+ remote := r.RemoteAddr
+ if r.Header.Get("X-Real-Ip") != "" {
+ remote = r.Header.Get("X-Real-Ip")
}
- }
+
+ count := 1
+ if m.Confv("record", []interface{}{r.URL.Path}) == nil {
+ m.Confv("record", []interface{}{r.URL.Path}, map[string]interface{}{
+ "remote": map[string]interface{}{remote: map[string]interface{}{"time": time.Now().Format("2006/01/02 15:04:05")}},
+ "count": count,
+ })
+ } else {
+ switch v := m.Confv("record", []interface{}{r.URL.Path, "count"}).(type) {
+ case int:
+ count = v
+ case float64:
+ count = int(v)
+ default:
+ count = 0
+ }
+
+ if m.Confv("record", []interface{}{r.URL.Path, "remote", remote}) == nil {
+ m.Confv("record", []interface{}{r.URL.Path, "count"}, count+1)
+ } else {
+ msg.Option("last_record_time", m.Confv("record", []interface{}{r.URL.Path, "remote", remote, "time"}))
+ }
+ m.Confv("record", []interface{}{r.URL.Path, "remote", remote}, map[string]interface{}{"time": time.Now().Format("2006/01/02 15:04:05")})
+ }
+ msg.Option("record_count", count)
+
+ for _, v := range r.Cookies() {
+ msg.Option(v.Name, v.Value)
+ }
+ for k, v := range r.Form {
+ msg.Add("option", k, v)
+ }
+
+ msg.Log("cmd", "%s [] %v", key, msg.Meta["option"])
+ msg.Put("option", "request", r).Put("option", "response", w)
+ hand(msg, msg.Target(), msg.Option("path"))
+
+ switch {
+ case msg.Has("directory"):
+ http.ServeFile(w, r, msg.Append("directory"))
+ case msg.Has("redirect"):
+ http.Redirect(w, r, msg.Append("redirect"), http.StatusFound)
+ case msg.Has("template"):
+ msg.Spawn().Cmd("/render", msg.Meta["template"])
+ case msg.Has("append"):
+ msg.Spawn().Copy(msg, "result").Copy(msg, "append").Cmd("/json")
+ default:
+ for _, v := range msg.Meta["result"] {
+ w.Write([]byte(v))
+ }
+ }
+ })
})
}
@@ -248,18 +280,20 @@ 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", "variable", "struct", "key", "key", "other")
- // yac.Cmd("train", "code", "define", "#define", "key", "other")
- //
+ 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", "def", "def", "key", "(", "other")
+ yac.Cmd("train", "code", "def", "class", "key", "other")
+ 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", "variable", "struct", "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: "服务密钥"}
@@ -294,6 +328,7 @@ 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: "路由数量"},
+ "record": &ctx.Config{Name: "record", Value: map[string]interface{}{}, Help: "访问记录"},
"wiki_dir": &ctx.Config{Name: "wiki_dir", Value: "usr/wiki", Help: "路由数量"},
"wiki_list_show": &ctx.Config{Name: "wiki_list_show", Value: map[string]interface{}{
"md": true,
@@ -1197,7 +1232,7 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
yac := m.Find("yac.parse4", true)
- msg := m.Sess("nfs").Cmd("dir", path.Join(m.Conf("wiki_dir"), m.Option("dir")), "dir_name", "path")
+ msg := m.Sess("nfs").Cmd("dir", path.Join(m.Conf("wiki_dir"), "src", m.Option("dir")), "dir_name", "path")
for i, v := range msg.Meta["filename"] {
name := strings.TrimSpace(v)
es := strings.Split(name, ".")
@@ -1205,6 +1240,7 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
case "pyc", "o", "gz", "tar":
continue
case "c":
+ case "py":
case "h":
default:
continue
@@ -1248,7 +1284,7 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
}
if key != "" {
m.Confv("define", strings.Join([]string{key, "position", "-2"}, "."), map[string]interface{}{
- "file": strings.TrimPrefix(name, m.Confx("wiki_dir")),
+ "file": strings.TrimPrefix(name, m.Confx("wiki_dir")+"/src"),
"line": line,
"type": l.Result(1),
})
@@ -1260,12 +1296,39 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
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 {
+ which := path.Join(m.Conf("wiki_dir"), m.Confx("which"))
+ st, _ := os.Stat(which)
+ if ls, e := ioutil.ReadFile(which); e == nil {
pre := false
es := strings.Split(m.Confx("which"), ".")
if len(es) > 0 {
switch es[len(es)-1] {
case "md":
+ m.Option("modify_count", 1)
+ m.Option("modify_time", st.ModTime().Format("2006/01/02 15:03:04"))
+
+ switch v := m.Confv("record", []interface{}{m.Option("path"), "local", "modify_count"}).(type) {
+ case int:
+ if m.Confv("record", []interface{}{m.Option("path"), "local", "modify_time"}).(string) != m.Option("modify_time") {
+ m.Confv("record", []interface{}{m.Option("path"), "local", "modify_time"}, m.Option("modify_time"))
+ m.Confv("record", []interface{}{m.Option("path"), "local", "modify_count"}, v+1)
+ }
+ m.Option("modify_count", v+1)
+ case float64:
+ if m.Confv("record", []interface{}{m.Option("path"), "local", "modify_time"}).(string) != m.Option("modify_time") {
+ m.Confv("record", []interface{}{m.Option("path"), "local", "modify_time"}, m.Option("modify_time"))
+ m.Confv("record", []interface{}{m.Option("path"), "local", "modify_count"}, v+1)
+ }
+ m.Option("modify_count", v+1)
+ case nil:
+ m.Confv("record", []interface{}{m.Option("path"), "local"}, map[string]interface{}{
+ "modify_count": m.Optioni("modify_count"),
+ "modify_time": m.Option("modify_time"),
+ })
+ default:
+ m.Log("fuck", "5")
+ }
+
ls = markdown.ToHTML(ls, nil, nil)
default:
pre = true
@@ -1288,7 +1351,7 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
if v, ok := m.Confv("define", m.Option("query")).(map[string]interface{}); ok {
for _, val := range v["position"].([]interface{}) {
value := val.(map[string]interface{})
- m.Add("append", "name", fmt.Sprintf("%v#hash_%v", value["file"], value["line"]))
+ m.Add("append", "name", fmt.Sprintf("src/%v#hash_%v", value["file"], value["line"]))
}
return
}
diff --git a/usr/template/common/wiki.html b/usr/template/common/wiki.html
index 2ad8bb88..3369db90 100644
--- a/usr/template/common/wiki.html
+++ b/usr/template/common/wiki.html
@@ -172,7 +172,7 @@ function tags(event) {
if (tag && tag.length > 0 && tags_list[tag]) {
var position = tags_list[tag].position;
if (position.length == 1) {
- jumpto("/wiki"+position[0].file+"#hash_"+position[0].line);
+ jumpto("/wiki/src/"+position[0].file+"#hash_"+position[0].line);
} else {
jumpto("/wiki/?query="+encodeURIComponent(tag));
}
@@ -217,9 +217,17 @@ window.onload = function() {
padding:0px;
height:16px;
}
+.record {
+ margin: 10px 40px;
+ /* float:right; */
+}
+ {{if option . "modify_time"|meta}}
+
上次修订时间: {{option . "modify_time"|meta}} 修订次数: {{option . "modify_count"|meta}}
+ {{end}}
+
上次阅读时间: {{option . "last_record_time"|meta}} 总访问量: {{option . "record_count"|meta}}
{{range option . "nline"|meta|list}}
@@ -237,10 +245,10 @@ window.onload = function() {
{{range $i, $v := append . "name"}}
-
-
+
{{end}}
diff --git a/usr/wiki/context.md b/usr/wiki/context.md
new file mode 100644
index 00000000..e8460bf1
--- /dev/null
+++ b/usr/wiki/context.md
@@ -0,0 +1,28 @@
+## 简介
+context 是用 golang 开发的一款系统级应用。
+
+- 一种新的应用框架,可以快速开发出各种实用工具。
+- 一种新的编程语言,可以用脚本编写各种业务应用。
+- 通过接口文本化,解除函数之间的硬性依赖,提高代码复用率。
+- 把每个函数当成一个服务来开发,把每个进程当一个集群来开发,实现微集群效应。
+- 每个函数既可以在浏览器中调用,也可以在命令行中调用,更可以当成库函数调用。
+
+### 项目进度
+- 2017.11.01 项目启动
+- 2018.07.30 1.0 发布
+
+### 相关链接
+- 开发者邮箱:
+- 源码:
+- 文档:
+
+### 源码安装
+首先安装好golang开发工具(参考: )。
+```
+$ git clone https://github.com/shylinux/context
+$ cd context && make
+$ bench
+> pwd
+> ls
+```
+
diff --git a/usr/wiki/golang.md b/usr/wiki/golang.md
new file mode 100644
index 00000000..bd487b6b
--- /dev/null
+++ b/usr/wiki/golang.md
@@ -0,0 +1,11 @@
+## 简介
+golang 是 google 开发的一种静态的强类型、编译型、并发型、并具有垃圾回收功能的编程语言。
+
+- 既有编译语言的严谨与高效,又具有脚本语言的动态与灵活。
+
+### 相关链接
+- 官网:
+- 源码:
+
+### 源码安装
+可以去官网下载各种安装包(),直接进行安装。