1
0
mirror of https://shylinux.com/x/ContextOS synced 2025-04-25 16:58:06 +08:00

vps add record

This commit is contained in:
shylinux 2018-09-08 06:25:31 +08:00
parent 84bba14ebd
commit f5a2880e6c
5 changed files with 163 additions and 48 deletions

View File

@ -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, "."), ".")

View File

@ -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
}

View File

@ -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; */
}
</style>
<div class="content">
<div class="toggle" title="点击,显示或隐藏目录" onclick="toggle()"></div>
{{if option . "modify_time"|meta}}
<div class="record">上次修订时间: {{option . "modify_time"|meta}} 修订次数: {{option . "modify_count"|meta}}</div>
{{end}}
<div class="record">上次阅读时间: {{option . "last_record_time"|meta}} 总访问量: {{option . "record_count"|meta}}</div>
<div class="texts">
<div class="number">
{{range option . "nline"|meta|list}}
@ -237,10 +245,10 @@ window.onload = function() {
<ul>
{{range $i, $v := append . "name"}}
<li class="link">
<div>
<code>{{option $msg "time" $i}}&nbsp;&nbsp;&nbsp;</code>
<a href="/wiki/{{option $msg "dir"|meta}}/{{$v}}{{option $msg "pend" $i}}">{{$v}}{{option $msg "pend" $i}}</a>
</div>
<div>
<code>{{option $msg "time" $i}}&nbsp;&nbsp;&nbsp;</code>
<a href="/wiki/{{option $msg "dir"|meta}}/{{$v}}{{option $msg "pend" $i}}">{{$v}}{{option $msg "pend" $i}}</a>
</div>
</li>
{{end}}
<ul>

28
usr/wiki/context.md Normal file
View File

@ -0,0 +1,28 @@
## 简介
context 是用 golang 开发的一款系统级应用。
- 一种新的应用框架,可以快速开发出各种实用工具。
- 一种新的编程语言,可以用脚本编写各种业务应用。
- 通过接口文本化,解除函数之间的硬性依赖,提高代码复用率。
- 把每个函数当成一个服务来开发,把每个进程当一个集群来开发,实现微集群效应。
- 每个函数既可以在浏览器中调用,也可以在命令行中调用,更可以当成库函数调用。
### 项目进度
- 2017.11.01 项目启动
- 2018.07.30 1.0 发布
### 相关链接
- 开发者邮箱: <shylinux@163.com>
- 源码: <https://github.com/shylinux/context>
- 文档: <https://shylinux.com/wiki/context.md>
### 源码安装
首先安装好golang开发工具(参考: <https://shylinux.com/wiki/golang.md>)。
```
$ git clone https://github.com/shylinux/context
$ cd context && make
$ bench
> pwd
> ls
```

11
usr/wiki/golang.md Normal file
View File

@ -0,0 +1,11 @@
## 简介
golang 是 google 开发的一种静态的强类型、编译型、并发型、并具有垃圾回收功能的编程语言。
- 既有编译语言的严谨与高效,又具有脚本语言的动态与灵活。
### 相关链接
- 官网: <https://golang.org/>
- 源码: <https://github.com/golang>
### 源码安装
可以去官网下载各种安装包(<https://golang.org/dl/>),直接进行安装。