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

tce opt web.post

This commit is contained in:
shaoying 2018-10-17 10:26:54 +08:00
parent 71cf3a7e3a
commit ec1a9c0fc8
8 changed files with 548 additions and 341 deletions

View File

@ -8,14 +8,14 @@
"加载插件"{{{
call plug#begin()
Plug 'vim-scripts/tComment'
Plug 'gcmt/taboo.vim'
Plug 'vim-scripts/tComment'
Plug 'tpope/vim-fugitive'
Plug 'airblade/vim-gitgutter'
Plug 'vim-airline/vim-airline'
Plug 'vim-airline/vim-airline-themes'
Plug 'ntpeters/vim-better-whitespace'
Plug 'easymotion/vim-easymotion'
nmap t ;;t
nmap T ;;T
Plug 'vim-scripts/taglist.vim'
let g:Tlist_WinWidth=45
@ -55,12 +55,14 @@ let g:syntastic_quiet_messages = { "regex": [
\ "Invalid variable name",
\ "Too many instance attributes",
\ "defined outside __init__",
\ "Catching too general exception Exception",
\ ] }
Plug 'Valloric/YouCompleteMe'
let g:syntastic_enable_signs = 1
let g:ycm_confirm_extra_conf=0
nnoremap gd :YcmCompleter GoToDeclaration<CR>
nnoremap gD :YcmCompleter GoToReferences<CR>
Plug 'benmills/vimux'
let mapleader=";"
@ -126,13 +128,14 @@ cnoremap jk <CR>
"}}}
" 编程配置{{{
set keywordprg=man\ -a
set splitbelow
set splitright
autocmd BufReadPost * normal `"
autocmd BufNewFile,BufReadPost *.shy set filetype=shy
autocmd BufNewFile,BufReadPost *.shy set commentstring=#%s
autocmd BufNewFile,BufReadPost *.conf set filetype=nginx
autocmd BufNewFile,BufReadPost *.go set foldmethod=syntax
command! RR wa | source ~/.vimrc |e
source ~/.vim_local
"}}}

View File

@ -51,7 +51,7 @@ ZSH_THEME="robbyrussell"
# Custom plugins may be added to ~/.oh-my-zsh/custom/plugins/
# Example format: plugins=(rails git textmate ruby lighthouse)
# Add wisely, as too many plugins slow down shell startup.
plugins=(tmux docker git)
plugins=(tmux git)
source $ZSH/oh-my-zsh.sh
source ~/.oh-my-zsh/plugins/z/z.sh

View File

@ -17,33 +17,31 @@ syn keyword shStatement if else elif end for
syn keyword shStatement let var
" ctx command
syn match shStatement "\(^\|\t\|$(\|\ \ \)cache"
syn match shStatement "\(^\|\t\|$(\|\ \ \)config"
syn match shStatement "\(^\|\t\|$(\|\ \ \)detail"
syn match shStatement "\(^\|\t\|$(\|\ \ \)option"
syn match shStatement "\(^\|\t\|$(\|\ \ \)append"
syn match shStatement "\(^\|\t\|$(\|\ \ \)result"
syn match shStatement "\(^\|\t\|$(\)cache"
syn match shStatement "\(^\|\t\|$(\)config"
syn match shStatement "\(^\|\t\|$(\)detail"
syn match shStatement "\(^\|\t\|$(\)option"
syn match shStatement "\(^\|\t\|$(\)append"
syn match shStatement "\(^\|\t\|$(\)result"
" ctx command
syn match shCommand "\(^\|\t\|$(\|\ \ \)command"
syn match shCommand "\(^\|\t\|$(\|\ \ \)context"
syn match shCommand "\(^\|\t\|$(\|\ \ \)message"
syn match shCommand "\(^\|\t\|$(\|\ \ \)session"
syn match shCommand "\(^\|\t\|$(\|\ \ \)server"
syn match shCommand "\(^\|\t\|$(\|\ \ \)right"
syn match shCommand "\(^\|\t\|$(\)message"
syn match shCommand "\(^\|\t\|$(\)session"
syn match shCommand "\(^\|\t\|$(\)context"
syn match shCommand "\(^\|\t\|$(\)server"
syn match shCommand "\(^\|\t\|$(\)command"
syn match shCommand "\(^\|\t\|$(\)right"
" tcp command
syn match shCommand "\(^\|\t\|$(\|\ \ \)listen"
syn match shCommand "\(^\|\t\|$(\)listen"
" web command
syn match shCommand "\(^\|\t\|$(\|\ \ \)client"
syn match shCommand "\(^\|\t\|$(\|\ \ \)serve\$"
syn match shCommand "\(^\|\t\|$(\|\ \ \)route"
syn match shCommand "\(^\|\t\|$(\)serve"
syn match shCommand "\(^\|\t\|$(\)route"
syn match shCommand "\(^\|\t\|$(\|\ \ \)open"
syn match shCommand "\(^\|\t\|$(\|\ \ \)cookie"
syn match shCommand "\(^\|\t\|$(\|\ \ \)login"
syn match shCommand "\(^\|\t\|$(\)open"
syn match shCommand "\(^\|\t\|$(\)cookie"
syn match shCommand "\(^\|\t\|$(\)login"
hi def link shComment Comment
hi def link shString String

View File

@ -73,10 +73,12 @@ func (cli *CLI) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server
s.Message = m
s.target = c
s.alias = map[string][]string{
"~": []string{"context"},
"!": []string{"message"},
"@": []string{"config"},
"$": []string{"cache"},
"~": []string{"context"},
"!": []string{"message"},
":": []string{"command"},
"::": []string{"command", "list"},
"@": []string{"config"},
"$": []string{"cache"},
}
return s

View File

@ -39,6 +39,8 @@ func Trans(arg ...interface{}) []string {
ls = append(ls, fmt.Sprintf("%t", val))
case int, int8, int16, int32, int64:
ls = append(ls, fmt.Sprintf("%d", val))
case float64:
ls = append(ls, fmt.Sprintf("%d", int(val)))
case []interface{}:
for _, v := range val {
switch val := v.(type) {
@ -68,15 +70,15 @@ func Trans(arg ...interface{}) []string {
return ls
}
func Chain(m *Message, data interface{}, args ...interface{}) interface{} {
if len(args) == 1 {
if arg, ok := args[0].([]string); ok {
args = args[:0]
for _, v := range arg {
args = append(args, v)
}
}
}
// if len(args) == 1 {
// if arg, ok := args[0].([]string); ok {
// args = args[:0]
// for _, v := range arg {
// args = append(args, v)
// }
// }
// }
//
root := data
for i := 0; i < len(args); i += 2 {
var parent interface{}
@ -2132,6 +2134,9 @@ var Index = &Context{Name: "ctx", Help: "模块中心",
"table_compact": &Config{Name: "table_compact", Value: "false", Help: "命令列表帮助"},
"table_col_sep": &Config{Name: "table_col_sep", Value: "\t", Help: "命令列表帮助"},
"table_row_sep": &Config{Name: "table_row_sep", Value: "\n", Help: "命令列表帮助"},
"page_offset": &Config{Name: "page_offset", Value: "0", Help: "列表偏移"},
"page_limit": &Config{Name: "page_limit", Value: "10", Help: "列表大小"},
},
Commands: map[string]*Command{
"help": &Command{Name: "help topic", Help: "帮助", Hand: func(m *Message, c *Context, key string, arg ...string) {
@ -2846,7 +2851,8 @@ var Index = &Context{Name: "ctx", Help: "模块中心",
}
}
if cache_name != "" && li > -1 {
m.Echo(m.Cap(cache_name, msg.Meta[cache_index][li]))
// m.Echo(m.Cap(cache_name, msg.Meta[cache_index][li]))
m.Echo(m.Cap(cache_name, fmt.Sprint(msg.Confv(m.Confx("body_response"), cache_index))))
} else {
m.Copy(msg, "result").Copy(msg, "append")
}
@ -2942,7 +2948,19 @@ var Index = &Context{Name: "ctx", Help: "模块中心",
"config": &Command{
Name: "config [all] [save|load file key...] [delete] [pop index] key [value...]|key name value help",
Help: "查看、读写、添加配置变量",
Form: map[string]int{
"chains": 1, "fields": 1,
"where_field": 1, "where_value": 1,
"sort_field": 1, "sort_order": 1,
"page_limit": 1, "page_offset": 1,
"select": 3,
},
Hand: func(m *Message, c *Context, key string, arg ...string) {
offset, e := strconv.Atoi(m.Confx("page_offset"))
m.Assert(e)
limit, e := strconv.Atoi(m.Confx("page_limit"))
m.Assert(e)
all := false
if len(arg) > 0 && arg[0] == "all" {
arg, all = arg[1:], true
@ -2977,7 +2995,8 @@ var Index = &Context{Name: "ctx", Help: "模块中心",
de.Decode(&save)
}
sort := "string"
sort_field := m.Option("sort_field")
sort_order := m.Option("sort_order")
m.BackTrace(func(m *Message) bool {
for k, v := range m.target.Configs {
switch action {
@ -3033,31 +3052,70 @@ var Index = &Context{Name: "ctx", Help: "模块中心",
if k != arg[0] {
continue
}
switch val := v.Value.(type) {
case map[string]string:
for k, _ := range val {
m.Add("append", "key", k)
m.Add("append", "val", m.Conf(arg[0], k))
value := m.Confv(arg[0])
if m.Options("chains") {
value = m.Confv(arg[0], strings.Split(m.Option("chains"), "."))
}
fields := map[string]bool{}
for _, k := range strings.Split(m.Option("fields"), " ") {
if k == "" {
continue
}
if fields[k] = true; len(fields) == 1 {
m.Meta["append"] = append(m.Meta["append"], "index")
}
m.Meta["append"] = append(m.Meta["append"], k)
}
m.Log("fuck", "what %v", fields)
switch val := value.(type) {
case map[string]interface{}:
for k, _ := range val {
m.Add("append", "key", k)
m.Add("append", "val", m.Conf(arg[0], k))
m.Add("append", "index", "0")
for k, v := range val {
if len(fields) == 0 || fields[k] {
m.Add("append", k, v)
}
}
case []string:
sort = "int"
for i, _ := range val {
m.Add("append", "key", i)
m.Add("append", "val", m.Conf(arg[0], k))
m.Log("fuck", "what %v", m.Meta)
case map[string]string:
m.Add("append", "index", "0")
for k, v := range val {
if len(fields) == 0 || fields[k] {
m.Add("append", k, v)
}
}
case []interface{}:
sort = "int"
for i, _ := range val {
m.Add("append", "key", i)
m.Add("append", "val", m.Conf(arg[0], k))
n := 0
for i, value := range val {
switch val := value.(type) {
case map[string]interface{}:
if m.Options("where_field") && m.Options("where_value") {
if !strings.Contains(fmt.Sprintf("%v", val[m.Option("where_field")]), m.Option("where_value")) {
continue
}
}
n++
if n <= offset || n > offset+limit {
continue
}
m.Add("append", "index", i)
for k, v := range val {
if len(fields) == 0 || fields[k] {
m.Add("append", k, v)
}
}
}
}
case string:
m.Echo(m.Conf(arg[0]))
case []string:
for i, v := range val {
m.Add("append", "index", i)
m.Add("append", "value", v)
}
default:
m.Echo("%v", Trans(val)[0])
}
default:
m.Echo("%v", m.Confv(arg[0], arg[1:]))
@ -3066,7 +3124,18 @@ var Index = &Context{Name: "ctx", Help: "模块中心",
}
}
return all
}).Sort("key", sort).Table()
})
if m.Sort(sort_field, sort_order); m.Has("index") {
for i := 0; i < len(m.Meta["index"]); i++ {
m.Meta["index"][i] = fmt.Sprintf("%d", i+offset)
}
}
if m.Has("select") {
m.Echo(m.Cap(m.Meta["select"][2], m.Meta[m.Meta["select"][1]][m.Optioni("select")]))
} else {
m.Table()
}
switch action {
case "save":
@ -3082,13 +3151,12 @@ var Index = &Context{Name: "ctx", Help: "模块中心",
m.Assert(e)
m.Echo("%s", string(buf))
}
}},
"cache": &Command{
Name: "cache [all|key [value]|key = value|key name value help|delete key]",
Help: "查看、读写、赋值、新建、删除缓存变量",
Hand: func(m *Message, c *Context, key string, arg ...string) {
switch len(arg) { //{{{
switch len(arg) {
case 0:
for k, v := range m.target.Caches {
m.Add("append", "key", k)

View File

@ -28,7 +28,6 @@ type MUX interface {
}
type WEB struct {
client *http.Client
*http.ServeMux
*http.Server
@ -274,12 +273,14 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
"nroute": &ctx.Cache{Name: "nroute", Value: "0", Help: "路由数量"},
},
Configs: map[string]*ctx.Config{
"brow_home": &ctx.Config{Name: "brow_home", Value: "http://localhost:9094", Help: "服务"},
"directory": &ctx.Config{Name: "directory", Value: "usr", Help: "服务目录"},
"address": &ctx.Config{Name: "address", Value: ":9094", Help: "服务地址"},
"protocol": &ctx.Config{Name: "protocol", Value: "http", Help: "服务协议"},
"cert": &ctx.Config{Name: "cert", Value: "etc/cert.pem", Help: "路由数量"},
"key": &ctx.Config{Name: "key", Value: "etc/key.pem", Help: "路由数量"},
"body_response": &ctx.Config{Name: "body_response", Value: "response", Help: "响应缓存"},
"method": &ctx.Config{Name: "method", Value: "GET", Help: "请求方法"},
"brow_home": &ctx.Config{Name: "brow_home", Value: "http://localhost:9094", Help: "服务"},
"directory": &ctx.Config{Name: "directory", Value: "usr", Help: "服务目录"},
"address": &ctx.Config{Name: "address", Value: ":9094", Help: "服务地址"},
"protocol": &ctx.Config{Name: "protocol", Value: "http", 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: "访问记录"},
"auto_create": &ctx.Config{Name: "auto_create(true/false)", Value: "true", Help: "路由数量"},
@ -456,64 +457,57 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
},
Commands: map[string]*ctx.Command{
"client": &ctx.Command{Name: "client address [output [editor]]", Help: "添加浏览器配置, address: 默认地址, output: 输出路径, editor: 编辑器", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
if _, e := m.Target().Server.(*WEB); m.Assert(e) && len(arg) > 0 {
uri, e := url.Parse(arg[0])
m.Assert(e)
m.Conf("method", "method", "GET", "请求方法")
m.Conf("protocol", "protocol", uri.Scheme, "服务协议")
m.Conf("hostname", "hostname", uri.Host, "服务主机")
uri, e := url.Parse(arg[0])
m.Assert(e)
m.Conf("method", "method", "GET", "请求方法")
m.Conf("protocol", "protocol", uri.Scheme, "服务协议")
m.Conf("hostname", "hostname", uri.Host, "服务主机")
dir, file := path.Split(uri.EscapedPath())
m.Conf("path", "path", dir, "服务路由")
m.Conf("file", "file", file, "服务文件")
m.Conf("query", "query", uri.RawQuery, "服务参数")
dir, file := path.Split(uri.EscapedPath())
m.Conf("path", "path", dir, "服务路由")
m.Conf("file", "file", file, "服务文件")
m.Conf("query", "query", uri.RawQuery, "服务参数")
if m.Conf("output", "output", "stdout", "文件缓存"); len(arg) > 1 {
m.Conf("output", arg[1])
}
if m.Conf("editor", "editor", "vim", "文件编辑器"); len(arg) > 2 {
m.Conf("editor", arg[2])
}
if m.Conf("output", "output", "stdout", "文件缓存"); len(arg) > 1 {
m.Conf("output", arg[1])
}
if m.Conf("editor", "editor", "vim", "文件编辑器"); len(arg) > 2 {
m.Conf("editor", arg[2])
}
}},
"cookie": &ctx.Command{Name: "cookie [create]|[name [value]]", Help: "读写浏览器的Cookie, create: 创建cookiejar, name: 变量名, value: 变量值", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
if _, ok := m.Target().Server.(*WEB); m.Assert(ok) {
switch len(arg) {
case 0:
for k, v := range m.Confv("cookie").(map[string]interface{}) {
m.Echo("%s: %v\n", k, v.(*http.Cookie).Value)
}
case 1:
if arg[0] == "create" {
m.Target().Configs["cookie"] = &ctx.Config{Name: "cookie", Value: map[string]interface{}{}, Help: "cookie"}
break
}
if v, ok := m.Confv("cookie", arg[0]).(*http.Cookie); ok {
m.Echo("%s", v.Value)
}
default:
if v, ok := m.Confv("cookie", arg[0]).(*http.Cookie); ok {
v.Value = arg[1]
} else {
m.Confv("cookie", arg[0], &http.Cookie{Name: arg[0], Value: arg[1]})
}
switch len(arg) {
case 0:
for k, v := range m.Confv("cookie").(map[string]interface{}) {
m.Echo("%s: %v\n", k, v.(*http.Cookie).Value)
}
case 1:
if arg[0] == "create" {
m.Target().Configs["cookie"] = &ctx.Config{Name: "cookie", Value: map[string]interface{}{}, Help: "cookie"}
break
}
if v, ok := m.Confv("cookie", arg[0]).(*http.Cookie); ok {
m.Echo("%s", v.Value)
}
default:
if m.Confv("cookie") == nil {
m.Target().Configs["cookie"] = &ctx.Config{Name: "cookie", Value: map[string]interface{}{}, Help: "cookie"}
}
if v, ok := m.Confv("cookie", arg[0]).(*http.Cookie); ok {
v.Value = arg[1]
} else {
m.Confv("cookie", arg[0], &http.Cookie{Name: arg[0], Value: arg[1]})
}
}
}},
"get": &ctx.Command{
Name: "get [method GET|POST] [file name filename] url arg...",
Help: "访问服务, method: 请求方法, file: 发送文件, url: 请求地址, arg: 请求参数",
Form: map[string]int{"method": 1, "headers": 2, "file": 2, "body_type": 1, "body": 1, "fields": 1, "value": 1, "json_route": 1, "json_key": 1},
"get": &ctx.Command{Name: "get [method GET|POST] url arg...",
Help: "访问服务, method: 请求方法, url: 请求地址, arg: 请求参数",
Form: map[string]int{"method": 1, "headers": 2, "content_type": 1, "body": 1, "path_value": 1, "body_response": 1},
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
if web, ok := m.Target().Server.(*WEB); m.Assert(ok) {
if web.client == nil {
web.client = &http.Client{}
}
if m.Has("value") {
args := strings.Split(m.Option("value"), " ")
if m.Has("path_value") {
values := []interface{}{}
for _, v := range args {
for _, v := range strings.Split(m.Option("path_value"), " ") {
if len(v) > 1 && v[0] == '$' {
values = append(values, m.Cap(v[1:]))
} else {
@ -525,107 +519,39 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
method := m.Confx("method")
uri := web.Merge(m, arg[0], arg[1:]...)
m.Log("info", "%s %s", method, uri)
m.Echo("%s: %s\n", method, uri)
body, _ := m.Optionv("body").(io.Reader)
var body io.Reader
index := strings.Index(uri, "?")
contenttype := ""
switch method {
case "POST":
if m.Options("file") {
file, e := os.Open(m.Meta["file"][1])
m.Assert(e)
defer file.Close()
if m.Option("body_type") == "json" {
contenttype = "application/json"
body = file
break
}
buf := &bytes.Buffer{}
writer := multipart.NewWriter(buf)
part, e := writer.CreateFormFile(m.Option("file"), filepath.Base(m.Meta["file"][1]))
m.Assert(e)
io.Copy(part, file)
for i := 0; i < len(arg)-1; i += 2 {
value := arg[i+1]
if len(arg[i+1]) > 1 {
switch arg[i+1][0] {
case '$':
value = m.Cap(arg[i+1][1:])
case '@':
value = m.Conf(arg[i+1][1:])
}
}
writer.WriteField(arg[i], value)
}
contenttype = writer.FormDataContentType()
body = buf
writer.Close()
} else if m.Option("body_type") == "json" {
if m.Options("body") {
data := []interface{}{}
for _, v := range arg[1:] {
if len(v) > 1 && v[0] == '$' {
v = m.Cap(v[1:])
}
data = append(data, v)
}
body = strings.NewReader(fmt.Sprintf(m.Option("body"), data...))
} else {
data := map[string]interface{}{}
for i := 1; i < len(arg)-1; i += 2 {
switch arg[i+1] {
case "false":
data[arg[i]] = false
case "true":
data[arg[i]] = true
default:
if len(arg[i+1]) > 1 && arg[i+1][0] == '$' {
data[arg[i]] = m.Cap(arg[i+1][1:])
} else {
data[arg[i]] = arg[i+1]
}
}
}
b, e := json.Marshal(data)
m.Assert(e)
body = bytes.NewReader(b)
}
contenttype = "application/json"
if index > -1 {
uri = uri[:index]
}
} else if index > 0 {
contenttype = "application/x-www-form-urlencoded"
body = strings.NewReader(uri[index+1:])
uri = uri[:index]
if method == "POST" && body == nil {
if index := strings.Index(uri, "?"); index > 0 {
uri, body = uri[:index], strings.NewReader(uri[index+1:])
}
}
req, e := http.NewRequest(method, uri, body)
m.Assert(e)
for i := 0; i < len(m.Meta["headers"]); i += 2 {
req.Header.Set(m.Meta["headers"][i], m.Meta["headers"][i+1])
}
if len(contenttype) > 0 {
req.Header.Set("Content-Type", contenttype)
m.Log("info", "content-type: %s", contenttype)
if m.Options("content_type") {
req.Header.Set("Content-Type", m.Option("content_type"))
}
switch cs := m.Confv("cookie").(type) {
case map[string]interface{}:
for _, v := range cs {
req.AddCookie(v.(*http.Cookie))
}
}
for _, v := range m.Confv("cookie").(map[string]interface{}) {
req.AddCookie(v.(*http.Cookie))
m.Log("info", "%s %s", req.Method, req.URL)
m.Echo("%s: %s\n", req.Method, req.URL)
for k, v := range req.Header {
m.Log("fuck", "%s: %s", k, v)
}
if web.client == nil {
web.client = &http.Client{}
}
res, e := web.client.Do(req)
m.Assert(e)
@ -634,134 +560,94 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
m.Log("info", "set-cookie %s: %v", v.Name, v.Value)
}
if m.Confs("logheaders") {
for k, v := range res.Header {
m.Log("info", "%s: %v", k, v)
}
}
if m.Confs("output") {
if _, e := os.Stat(m.Conf("output")); e == nil {
name := path.Join(m.Conf("output"), fmt.Sprintf("%d", time.Now().Unix()))
f, e := os.Create(name)
m.Assert(e)
io.Copy(f, res.Body)
if m.Confs("editor") {
cmd := exec.Command(m.Conf("editor"), name)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Run()
} else {
m.Echo("write to %s\n", name)
}
return
}
}
buf, e := ioutil.ReadAll(res.Body)
m.Assert(e)
var result interface{}
ct := res.Header.Get("Content-Type")
if len(ct) >= 16 && ct[:16] == "application/json" {
var result interface{}
switch {
case strings.HasPrefix(ct, "application/json"):
json.Unmarshal(buf, &result)
m.Option("response_json", result)
if m.Has("json_route") {
routes := strings.Split(m.Option("json_route"), ".")
for _, k := range routes {
if len(k) > 0 && k[0] == '$' {
k = m.Cap(k[1:])
}
switch r := result.(type) {
case map[string]interface{}:
result = r[k]
}
}
}
fields := map[string]bool{}
for _, k := range strings.Split(m.Option("fields"), " ") {
if k == "" {
continue
}
if fields[k] = true; len(fields) == 1 {
m.Meta["append"] = append(m.Meta["append"], "index")
}
m.Meta["append"] = append(m.Meta["append"], k)
}
if len(fields) > 0 {
switch ret := result.(type) {
case map[string]interface{}:
m.Append("index", "0")
for k, v := range ret {
switch value := v.(type) {
case string:
m.Append(k, strings.Replace(value, "\n", " ", -1))
case float64:
m.Append(k, fmt.Sprintf("%d", int(value)))
default:
if _, ok := fields[k]; ok {
m.Append(k, fmt.Sprintf("%v", value))
}
}
}
case []interface{}:
for i, r := range ret {
m.Add("append", "index", i)
if rr, ok := r.(map[string]interface{}); ok {
for k, v := range rr {
switch value := v.(type) {
case string:
if _, ok := fields[k]; len(fields) == 0 || ok {
m.Add("append", k, strings.Replace(value, "\n", " ", -1))
}
case float64:
if _, ok := fields[k]; len(fields) == 0 || ok {
m.Add("append", k, fmt.Sprintf("%d", int64(value)))
}
case bool:
if _, ok := fields[k]; len(fields) == 0 || ok {
m.Add("append", k, fmt.Sprintf("%v", value))
}
case map[string]interface{}:
for kk, vv := range value {
key := k + "." + kk
if _, ok := fields[key]; len(fields) == 0 || ok {
m.Add("append", key, strings.Replace(fmt.Sprintf("%v", vv), "\n", " ", -1))
}
}
default:
if _, ok := fields[k]; ok {
m.Add("append", k, fmt.Sprintf("%v", value))
}
}
}
}
}
if m.Has("json_key") {
m.Sort(m.Option("json_key"))
}
m.Meta["index"] = nil
for i, _ := range ret {
m.Add("append", "index", i)
}
}
}
}
if m.Table(); len(m.Meta["append"]) == 0 {
m.Echo("%s", string(buf))
default:
result = string(buf)
}
m.Target().Configs[m.Confx("body_response")] = &ctx.Config{Value: result}
m.Echo(string(buf))
}
}},
"post": &ctx.Command{Name: "post", Help: "post请求", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
msg := m.Spawn().Cmd("get", "method", "POST", arg)
m.Copy(msg, "result").Copy(msg, "append")
}},
"post": &ctx.Command{Name: "post [file fieldname filename]", Help: "post请求",
Form: map[string]int{"file": 2, "content_type": 1},
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
msg := m.Spawn()
if m.Has("file") {
file, e := os.Open(m.Meta["file"][1])
m.Assert(e)
defer file.Close()
buf := &bytes.Buffer{}
writer := multipart.NewWriter(buf)
writer.SetBoundary(fmt.Sprintf("\r\n--%s--\r\n", writer.Boundary()))
part, e := writer.CreateFormFile(m.Option("file"), filepath.Base(m.Meta["file"][1]))
m.Assert(e)
io.Copy(part, file)
// for i := 0; i < len(arg)-1; i += 2 {
// value := arg[i+1]
// if len(arg[i+1]) > 1 {
// switch arg[i+1][0] {
// case '$':
// value = m.Cap(arg[i+1][1:])
// case '@':
// value = m.Conf(arg[i+1][1:])
// }
// }
// writer.WriteField(arg[i], value)
// }
writer.Close()
msg.Optionv("body", buf)
msg.Option("content_type", writer.FormDataContentType())
msg.Option("headers", "Content-Length", buf.Len())
} else if m.Option("content_type") == "json" {
data := map[string]interface{}{}
for i := 1; i < len(arg)-1; i += 2 {
switch arg[i+1] {
case "false":
data[arg[i]] = false
case "true":
data[arg[i]] = true
default:
if len(arg[i+1]) > 1 && arg[i+1][0] == '$' {
data[arg[i]] = m.Cap(arg[i+1][1:])
} else {
data[arg[i]] = arg[i+1]
}
}
}
b, e := json.Marshal(data)
m.Assert(e)
msg.Optionv("body", bytes.NewReader(b))
msg.Option("content_type", "application/json")
arg = arg[:1]
} else if m.Option("content_type") == "json_fmt" {
data := []interface{}{}
for _, v := range arg[2:] {
if len(v) > 1 && v[0] == '$' {
v = m.Cap(v[1:])
} else if len(v) > 1 && v[0] == '@' {
v = m.Cap(v[1:])
}
data = append(data, v)
}
msg.Optionv("body", strings.NewReader(fmt.Sprintf(arg[1], data...)))
msg.Option("content_type", "application/json")
arg = arg[:1]
} else {
msg.Option("content_type", "application/x-www-form-urlencoded")
}
msg.Cmd("get", "method", "POST", arg)
m.Copy(msg, "result").Copy(msg, "append")
}},
"brow": &ctx.Command{Name: "brow url", Help: "浏览网页", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
url := m.Confx("brow_home", arg, 0)
switch runtime.GOOS {
@ -1220,25 +1106,18 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
if len(m.Meta["append"]) > 0 {
meta["append"] = m.Meta["append"]
for _, v := range m.Meta["append"] {
m.Log("json", "won %v %v", v, m.Meta[v])
if _, ok := m.Data[v]; ok {
meta[v] = m.Data[v]
m.Log("json", "1won %v %v", v, meta[v])
m.Log("json", "1won %v %v", v, meta[v], m.Meta[v])
} else if _, ok := m.Meta[v]; ok {
m.Log("json", "2won %v %v", v, meta[v])
meta[v] = m.Meta[v]
}
m.Log("json", "won %v %v", v, meta[v])
}
}
if b, e := json.Marshal(meta); m.Assert(e) {
w.Header().Set("Content-Type", "application/javascript")
m.Log("json", "won %v", string(b))
w.Write(b)
}
}},
"/paste": &ctx.Command{Name: "/paste", Help: "应用示例", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
if login := m.Spawn().Cmd("/login"); login.Has("redirect") {
@ -1246,6 +1125,13 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
}
}},
"/upload": &ctx.Command{Name: "/upload", Help: "应用示例", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
r := m.Optionv("request").(*http.Request)
f, h, e := r.FormFile("file")
lf, e := os.Create(fmt.Sprintf("tmp/%s", h.Filename))
m.Assert(e)
io.Copy(lf, f)
}},
"user": &ctx.Command{Name: "user", Help: "应用示例", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
aaa := m.Sess("aaa")
m.Spawn().Cmd("get", fmt.Sprintf("%suser/get", aaa.Conf("wx_api")), "access_token", aaa.Cap("access_token"))
@ -1293,6 +1179,264 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
m.Appendv("lists", lists)
m.Log("log", "%v", lists)
}},
"old_get": &ctx.Command{
Name: "get [method GET|POST] [file name filename] url arg...",
Help: "访问服务, method: 请求方法, file: 发送文件, url: 请求地址, arg: 请求参数",
Form: map[string]int{"method": 1, "content_type": 1, "headers": 2, "file": 2, "body_type": 1, "body": 1, "fields": 1, "value": 1, "json_route": 1, "json_key": 1},
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
if web, ok := m.Target().Server.(*WEB); m.Assert(ok) {
if web.client == nil {
web.client = &http.Client{}
}
if m.Has("value") {
args := strings.Split(m.Option("value"), " ")
values := []interface{}{}
for _, v := range args {
if len(v) > 1 && v[0] == '$' {
values = append(values, m.Cap(v[1:]))
} else {
values = append(values, v)
}
}
arg[0] = fmt.Sprintf(arg[0], values...)
}
method := m.Confx("method")
uri := web.Merge(m, arg[0], arg[1:]...)
m.Log("info", "%s %s", method, uri)
m.Echo("%s: %s\n", method, uri)
var body io.Reader
index := strings.Index(uri, "?")
content_type := ""
switch method {
case "POST":
if m.Options("file") {
file, e := os.Open(m.Meta["file"][1])
m.Assert(e)
defer file.Close()
if m.Option("body_type") == "json" {
content_type = "application/json"
body = file
break
}
buf := &bytes.Buffer{}
writer := multipart.NewWriter(buf)
part, e := writer.CreateFormFile(m.Option("file"), filepath.Base(m.Meta["file"][1]))
m.Assert(e)
io.Copy(part, file)
for i := 0; i < len(arg)-1; i += 2 {
value := arg[i+1]
if len(arg[i+1]) > 1 {
switch arg[i+1][0] {
case '$':
value = m.Cap(arg[i+1][1:])
case '@':
value = m.Conf(arg[i+1][1:])
}
}
writer.WriteField(arg[i], value)
}
content_type = writer.FormDataContentType()
body = buf
writer.Close()
} else if m.Option("body_type") == "json" {
if m.Options("body") {
data := []interface{}{}
for _, v := range arg[1:] {
if len(v) > 1 && v[0] == '$' {
v = m.Cap(v[1:])
}
data = append(data, v)
}
body = strings.NewReader(fmt.Sprintf(m.Option("body"), data...))
} else {
data := map[string]interface{}{}
for i := 1; i < len(arg)-1; i += 2 {
switch arg[i+1] {
case "false":
data[arg[i]] = false
case "true":
data[arg[i]] = true
default:
if len(arg[i+1]) > 1 && arg[i+1][0] == '$' {
data[arg[i]] = m.Cap(arg[i+1][1:])
} else {
data[arg[i]] = arg[i+1]
}
}
}
b, e := json.Marshal(data)
m.Assert(e)
body = bytes.NewReader(b)
}
content_type = "application/json"
if index > -1 {
uri = uri[:index]
}
} else if index > 0 {
content_type = "application/x-www-form-urlencoded"
body = strings.NewReader(uri[index+1:])
uri = uri[:index]
}
}
req, e := http.NewRequest(method, uri, body)
m.Assert(e)
for i := 0; i < len(m.Meta["headers"]); i += 2 {
req.Header.Set(m.Meta["headers"][i], m.Meta["headers"][i+1])
}
if len(content_type) > 0 {
req.Header.Set("Content-Type", content_type)
m.Log("info", "content-type: %s", content_type)
}
for _, v := range m.Confv("cookie").(map[string]interface{}) {
req.AddCookie(v.(*http.Cookie))
}
res, e := web.client.Do(req)
m.Assert(e)
for _, v := range res.Cookies() {
m.Confv("cookie", v.Name, v)
m.Log("info", "set-cookie %s: %v", v.Name, v.Value)
}
if m.Confs("logheaders") {
for k, v := range res.Header {
m.Log("info", "%s: %v", k, v)
}
}
if m.Confs("output") {
if _, e := os.Stat(m.Conf("output")); e == nil {
name := path.Join(m.Conf("output"), fmt.Sprintf("%d", time.Now().Unix()))
f, e := os.Create(name)
m.Assert(e)
io.Copy(f, res.Body)
if m.Confs("editor") {
cmd := exec.Command(m.Conf("editor"), name)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Run()
} else {
m.Echo("write to %s\n", name)
}
return
}
}
buf, e := ioutil.ReadAll(res.Body)
m.Assert(e)
ct := res.Header.Get("Content-Type")
if len(ct) >= 16 && ct[:16] == "application/json" {
var result interface{}
json.Unmarshal(buf, &result)
m.Option("response_json", result)
if m.Has("json_route") {
routes := strings.Split(m.Option("json_route"), ".")
for _, k := range routes {
if len(k) > 0 && k[0] == '$' {
k = m.Cap(k[1:])
}
switch r := result.(type) {
case map[string]interface{}:
result = r[k]
}
}
}
fields := map[string]bool{}
for _, k := range strings.Split(m.Option("fields"), " ") {
if k == "" {
continue
}
if fields[k] = true; len(fields) == 1 {
m.Meta["append"] = append(m.Meta["append"], "index")
}
m.Meta["append"] = append(m.Meta["append"], k)
}
if len(fields) > 0 {
switch ret := result.(type) {
case map[string]interface{}:
m.Append("index", "0")
for k, v := range ret {
switch value := v.(type) {
case string:
m.Append(k, strings.Replace(value, "\n", " ", -1))
case float64:
m.Append(k, fmt.Sprintf("%d", int(value)))
default:
if _, ok := fields[k]; ok {
m.Append(k, fmt.Sprintf("%v", value))
}
}
}
case []interface{}:
for i, r := range ret {
m.Add("append", "index", i)
if rr, ok := r.(map[string]interface{}); ok {
for k, v := range rr {
switch value := v.(type) {
case string:
if _, ok := fields[k]; len(fields) == 0 || ok {
m.Add("append", k, strings.Replace(value, "\n", " ", -1))
}
case float64:
if _, ok := fields[k]; len(fields) == 0 || ok {
m.Add("append", k, fmt.Sprintf("%d", int64(value)))
}
case bool:
if _, ok := fields[k]; len(fields) == 0 || ok {
m.Add("append", k, fmt.Sprintf("%v", value))
}
case map[string]interface{}:
for kk, vv := range value {
key := k + "." + kk
if _, ok := fields[key]; len(fields) == 0 || ok {
m.Add("append", key, strings.Replace(fmt.Sprintf("%v", vv), "\n", " ", -1))
}
}
default:
if _, ok := fields[k]; ok {
m.Add("append", k, fmt.Sprintf("%v", value))
}
}
}
}
}
if m.Has("json_key") {
m.Sort(m.Option("json_key"))
}
m.Meta["index"] = nil
for i, _ := range ret {
m.Add("append", "index", i)
}
}
}
}
if m.Table(); len(m.Meta["append"]) == 0 {
m.Echo("%s", string(buf))
}
}
}},
},
}

View File

@ -5,10 +5,6 @@ import (
"contexts/web"
)
type JIRA struct {
web.WEB
}
var Index = &ctx.Context{Name: "jira", Help: "任务中心",
Caches: map[string]*ctx.Cache{},
Configs: map[string]*ctx.Config{},
@ -20,7 +16,7 @@ var Index = &ctx.Context{Name: "jira", Help: "任务中心",
}
func init() {
jira := &JIRA{}
jira := &web.WEB{}
jira.Context = Index
web.Index.Register(Index, jira)
}

View File

@ -9,10 +9,6 @@ import (
"net/http"
)
type LARK struct {
web.WEB
}
var Index = &ctx.Context{Name: "lark", Help: "会议中心",
Caches: map[string]*ctx.Cache{},
Configs: map[string]*ctx.Config{
@ -42,7 +38,7 @@ var Index = &ctx.Context{Name: "lark", Help: "会议中心",
}
func init() {
lark := &LARK{}
lark := &web.WEB{}
lark.Context = Index
web.Index.Register(Index, lark)
}