diff --git a/base/web/share.go b/base/web/share.go index cc0d3557..0c902446 100644 --- a/base/web/share.go +++ b/base/web/share.go @@ -28,6 +28,17 @@ func _share_domain(m *ice.Message) string { return link } func _share_cache(m *ice.Message, arg ...string) { + if pod := m.Option(kit.SSH_POD); pod != "" { + m.Option(kit.SSH_POD, "") + msg := m.Cmd(SPACE, pod, CACHE, arg[0]) + if msg.Append(kit.MDB_FILE) == "" { + m.Render(ice.RENDER_RESULT, msg.Append(kit.MDB_TEXT)) + } else { + m.Option(kit.SSH_POD, pod) + _share_local(m, msg.Append(kit.MDB_FILE)) + } + return + } msg := m.Cmd(CACHE, arg[0]) m.Render(ice.RENDER_DOWNLOAD, msg.Append(kit.MDB_FILE), msg.Append(kit.MDB_TYPE), msg.Append(kit.MDB_NAME)) } diff --git a/core/chat/files.go b/core/chat/files.go index bd738e31..eccbd585 100644 --- a/core/chat/files.go +++ b/core/chat/files.go @@ -12,7 +12,9 @@ const FILES = "files" func init() { Index.Merge(&ice.Context{ Configs: map[string]*ice.Config{ - FILES: {Name: FILES, Help: "文件夹", Value: kit.Data(kit.MDB_SHORT, kit.MDB_DATA)}, + FILES: {Name: FILES, Help: "文件夹", Value: kit.Data( + kit.MDB_SHORT, kit.MDB_DATA, kit.MDB_FIELD, "time,hash,type,name,size", + )}, }, Commands: map[string]*ice.Command{ FILES: {Name: "files hash auto upload", Help: "文件夹", Action: map[string]*ice.Action{ @@ -24,7 +26,7 @@ func init() { m.Cmdy(mdb.DELETE, m.Prefix(FILES), "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH)) }}, }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Fields(len(arg) == 0, "time,size,type,name,hash") + m.Fields(len(arg) == 0, m.Conf(FILES, kit.META_FIELD)) m.Cmd(mdb.SELECT, m.Prefix(FILES), "", mdb.HASH, kit.MDB_HASH, arg).Table(func(index int, value map[string]string, head []string) { link := kit.MergeURL("/share/cache/"+value[kit.MDB_DATA], "pod", m.Option(ice.MSG_USERPOD)) m.Push("", value, kit.Split(m.Option(ice.MSG_FIELDS))) diff --git a/logs.go b/logs.go index 63e68fb2..358fc6c6 100644 --- a/logs.go +++ b/logs.go @@ -77,7 +77,11 @@ func (m *Message) Info(str string, arg ...interface{}) *Message { return m.log(LOG_INFO, str, arg...) } func (m *Message) Cost(arg ...interface{}) *Message { - list := []string{m.Format("cost")} + list := []string{m.Format("cost"), m.join(arg...)} + return m.log(LOG_COST, strings.Join(list, " ")) +} +func (m *Message) join(arg ...interface{}) string { + list := []string{} for i := 0; i < len(arg); i += 2 { if i == len(arg)-1 { list = append(list, kit.Format(arg[i])) @@ -85,7 +89,7 @@ func (m *Message) Cost(arg ...interface{}) *Message { list = append(list, kit.Format(arg[i])+":", kit.Format(arg[i+1])) } } - return m.log(LOG_COST, strings.Join(list, " ")) + return strings.Join(list, " ") } func (m *Message) Warn(err bool, arg ...interface{}) bool { if !err || len(m.meta[MSG_RESULT]) > 0 && m.meta[MSG_RESULT][0] == ErrWarn { @@ -93,7 +97,7 @@ func (m *Message) Warn(err bool, arg ...interface{}) bool { } m.meta[MSG_RESULT] = kit.Simple(ErrWarn, arg) - m.log(LOG_WARN, fmt.Sprint(arg...)) + m.log(LOG_WARN, m.join(arg)) return err } func (m *Message) Error(err bool, str string, arg ...interface{}) bool { diff --git a/misc.go b/misc.go index 3e3aa10a..a9f77ddf 100644 --- a/misc.go +++ b/misc.go @@ -257,7 +257,9 @@ func (m *Message) Render(cmd string, args ...interface{}) *Message { if len(args) == 1 { args = append(args, m) } + m.Debug("what %v", args) if res, err := kit.Render(args[0].(string), args[1]); m.Assert(err) { + m.Debug("what") m.Echo(string(res)) } } @@ -266,6 +268,9 @@ func (m *Message) Render(cmd string, args ...interface{}) *Message { func (m *Message) RenderResult(args ...interface{}) *Message { return m.Render(RENDER_RESULT, args...) } +func (m *Message) RenderTemplate(args ...interface{}) *Message { + return m.Render(RENDER_TEMPLATE, args...) +} func (m *Message) RenderDownload(args ...interface{}) *Message { return m.Render(RENDER_DOWNLOAD, args...) } diff --git a/misc/wx/wx.go b/misc/wx/wx.go index f088ef6f..47f85b52 100644 --- a/misc/wx/wx.go +++ b/misc/wx/wx.go @@ -1,302 +1,22 @@ package wx import ( - "crypto/sha1" - "encoding/hex" - "encoding/xml" - "fmt" - "strings" - "time" - ice "github.com/shylinux/icebergs" - "github.com/shylinux/icebergs/base/aaa" - "github.com/shylinux/icebergs/base/cli" - "github.com/shylinux/icebergs/base/mdb" "github.com/shylinux/icebergs/base/web" "github.com/shylinux/icebergs/core/chat" - "github.com/shylinux/icebergs/core/wiki" - kit "github.com/shylinux/toolkits" ) -func _wx_sign(m *ice.Message, nonce, stamp string) string { - b := sha1.Sum([]byte(strings.Join(kit.Sort([]string{ - fmt.Sprintf("jsapi_ticket=%s", m.Cmdx(ACCESS, TICKET)), - fmt.Sprintf("url=%s", m.Option(ice.MSG_USERWEB)), - fmt.Sprintf("timestamp=%s", stamp), - fmt.Sprintf("noncestr=%s", nonce), - }), "&"))) - return hex.EncodeToString(b[:]) -} -func _wx_config(m *ice.Message, nonce string) { - m.Option(APPID, m.Conf(LOGIN, kit.Keym(APPID))) - m.Option("script", m.Conf(LOGIN, kit.Keym("script"))) - m.Option("signature", _wx_sign(m, m.Option("noncestr", nonce), m.Option("timestamp", kit.Format(time.Now().Unix())))) -} - -func _wx_parse(m *ice.Message) { - data := struct { - FromUserName string - ToUserName string - CreateTime int64 - MsgId int64 - Event string - MsgType string - Content string - }{} - xml.NewDecoder(m.R.Body).Decode(&data) - m.Debug("data: %#v", data) - - m.Option("FromUserName", data.FromUserName) - m.Option("ToUserName", data.ToUserName) - m.Option("CreateTime", data.CreateTime) - m.Option("MsgId", data.MsgId) - - m.Option("Event", data.Event) - m.Option("MsgType", data.MsgType) - m.Option("Content", data.Content) -} -func _wx_reply(m *ice.Message, tmpl string) { - m.Option(ice.MSG_OUTPUT, ice.RENDER_RESULT) - res, _ := kit.Render(m.Conf(LOGIN, kit.Keym(kit.MDB_TEMPLATE, tmpl)), m) - - m.Set(ice.MSG_RESULT) - m.Echo(string(res)) -} -func _wx_action(m *ice.Message) { - m.Option(ice.MSG_OUTPUT, ice.RENDER_RESULT) - m.Set(ice.MSG_RESULT) - - m.Echo(` - - -%s - -`, m.Option("ToUserName"), m.Option("FromUserName"), m.Option("CreateTime"), "news") - - count := 0 - m.Table(func(index int, value map[string]string, head []string) { count++ }) - m.Echo(`%d`, count) - - m.Echo(``) - m.Table(func(index int, value map[string]string, head []string) { - m.Echo(` -<![CDATA[%s]]> - - - - -`, value[wiki.TITLE], value[wiki.SPARK], value[wiki.IMAGE], value[wiki.REFER]) - }) - m.Echo(``) - m.Echo(``) - - m.Debug("echo: %v", m.Result()) -} - -const ( - LOGIN = "login" - APPID = "appid" - APPMM = "appmm" - TOKEN = "token" - EXPIRE = "expire" - TICKET = "ticket" - EXPIRES = "expires" - QRCODE = "qrcode" - CONFIG = "config" - WEIXIN = "weixin" - - ERRCODE = "errcode" - ERRMSG = "errmsg" -) -const ( - ACCESS = "access" - MENU = "menu" -) const WX = "wx" var Index = &ice.Context{Name: WX, Help: "公众号", - Configs: map[string]*ice.Config{ - LOGIN: {Name: LOGIN, Help: "认证", Value: kit.Data( - "script", "https://res.wx.qq.com/open/js/jweixin-1.6.0.js", - WEIXIN, "https://api.weixin.qq.com", APPID, "", APPMM, "", TOKEN, "", - kit.MDB_TEMPLATE, kit.Dict(kit.MDB_TEXT, text), MENU, []interface{}{ - kit.Dict(wiki.TITLE, "网站主页", wiki.SPARK, "点击进入", wiki.REFER, "https://shylinux.com", - wiki.IMAGE, "https://shylinux.com/share/local/usr/publish/3f265cd2455053b68976bc63bdd432d4.jpeg", - ), - kit.Dict(wiki.TITLE, "产品工具", wiki.SPARK, "点击进入", wiki.REFER, "https://shylinux.com?river=product", - wiki.IMAGE, "https://shylinux.com/share/local/usr/publish/3f265cd2455053b68976bc63bdd432d4.jpeg", - ), - kit.Dict(wiki.TITLE, "研发工具", wiki.SPARK, "点击进入", wiki.REFER, "https://shylinux.com?river=project", - wiki.IMAGE, "https://shylinux.com/share/local/usr/publish/3f265cd2455053b68976bc63bdd432d4.jpeg", - ), - kit.Dict(wiki.TITLE, "测试工具", wiki.SPARK, "点击进入", wiki.REFER, "https://shylinux.com?river=profile", - wiki.IMAGE, "https://shylinux.com/share/local/usr/publish/3f265cd2455053b68976bc63bdd432d4.jpeg", - ), - }, - )}, - "favor": {Name: "favor", Help: "收藏", Value: kit.Data(kit.MDB_SHORT, kit.MDB_TEXT)}, - "favor2": {Name: "favor2", Help: "收藏", Value: kit.Data(kit.MDB_SHORT, kit.MDB_LINK)}, - }, Commands: map[string]*ice.Command{ ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Load() - m.Cmd(web.SPIDE, mdb.CREATE, WEIXIN, m.Conf(LOGIN, kit.Keym(WEIXIN))) }}, ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Save() }}, - - ACCESS: {Name: "access appid auto menu qrcode ticket token login", Help: "认证", Action: map[string]*ice.Action{ - LOGIN: {Name: "login appid appmm token", Help: "登录", Hand: func(m *ice.Message, arg ...string) { - m.Conf(LOGIN, kit.Keym(APPID), m.Option(APPID)) - m.Conf(LOGIN, kit.Keym(APPMM), m.Option(APPMM)) - m.Conf(LOGIN, kit.Keym(TOKEN), m.Option(TOKEN)) - }}, - TOKEN: {Name: "token", Help: "令牌", Hand: func(m *ice.Message, arg ...string) { - if now := time.Now().Unix(); m.Conf(LOGIN, kit.Keym(ACCESS, TOKEN)) == "" || now > kit.Int64(m.Conf(LOGIN, kit.Keym(ACCESS, EXPIRE))) { - msg := m.Cmd(web.SPIDE, WEIXIN, web.SPIDE_GET, "/cgi-bin/token?grant_type=client_credential", - APPID, m.Conf(LOGIN, kit.Keym(APPID)), "secret", m.Conf(LOGIN, kit.Keym(APPMM))) - if m.Warn(msg.Append(ERRCODE) != "", "%v: %v", msg.Append(ERRCODE), msg.Append(ERRMSG)) { - return - } - - m.Conf(LOGIN, kit.Keym(ACCESS, EXPIRE), now+kit.Int64(msg.Append("expires_in"))) - m.Conf(LOGIN, kit.Keym(ACCESS, TOKEN), msg.Append("access_token")) - } - m.Echo(m.Conf(LOGIN, kit.Keym(ACCESS, TOKEN))) - }}, - TICKET: {Name: "ticket", Help: "票据", Hand: func(m *ice.Message, arg ...string) { - if now := time.Now().Unix(); m.Conf(LOGIN, kit.Keym(ACCESS, TICKET)) == "" || now > kit.Int64(m.Conf(LOGIN, kit.Keym(ACCESS, EXPIRES))) { - msg := m.Cmd(web.SPIDE, WEIXIN, web.SPIDE_GET, "/cgi-bin/ticket/getticket?type=jsapi", - "access_token", m.Cmdx(ACCESS, TOKEN)) - if m.Warn(msg.Append(ERRCODE) != "0", msg.Append(ERRCODE), msg.Append(ERRMSG)) { - return - } - - m.Conf(LOGIN, kit.Keym(ACCESS, EXPIRES), now+kit.Int64(msg.Append("expires_in"))) - m.Conf(LOGIN, kit.Keym(ACCESS, TICKET), msg.Append(TICKET)) - } - m.Echo(m.Conf(LOGIN, kit.Keym(ACCESS, TICKET))) - }}, - QRCODE: {Name: "qrcode", Help: "扫码", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(web.SPIDE, WEIXIN, web.SPIDE_POST, "/cgi-bin/qrcode/create?access_token="+m.Cmdx(ACCESS, TOKEN), - web.SPIDE_DATA, kit.Format(`{"expire_seconds": 604800, "action_name": "QR_STR_SCENE", "action_info": {"scene": {"scene_str": "test"}}}`)) - m.EchoQRCode(m.Append("url")) - }}, - CONFIG: {Name: "config", Help: "配置", Hand: func(m *ice.Message, arg ...string) { - _wx_config(m, "some") - }}, - - mdb.INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) {}}, - }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Echo(m.Conf(LOGIN, kit.Keym(APPID))) - }}, - - MENU: {Name: "menu name auto", Help: "菜单", Action: map[string]*ice.Action{ - mdb.CREATE: {Name: "create", Help: "添加", Hand: func(m *ice.Message, arg ...string) { - share := m.Cmdx(web.SHARE, mdb.CREATE, kit.MDB_TYPE, web.LOGIN, - aaa.USERNAME, m.Option(ice.MSG_USERNAME), aaa.USERROLE, m.Option(ice.MSG_USERROLE)) - kit.Fetch(m.Confv(LOGIN, kit.Keym(MENU)), func(index int, value map[string]interface{}) { - m.Push("", value, kit.Split("title,spark,image")) - m.Push(wiki.REFER, kit.MergeURL(kit.Format(value[wiki.REFER]), web.SHARE, share)) - }) - }}, - }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - kit.Fetch(m.Confv(LOGIN, kit.Keym(MENU)), func(index int, value map[string]interface{}) { - m.Push("", value, kit.Split("title,spark,refer,image")) - }) - }}, - - "favor": {Name: "favor name auto create", Help: "收藏", Action: map[string]*ice.Action{ - mdb.CREATE: {Name: "create name text", Help: "添加", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(mdb.INSERT, m.Prefix("favor"), "", mdb.HASH, arg) - }}, - mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(mdb.DELETE, m.Prefix("favor"), "", mdb.HASH, kit.MDB_NAME, m.Option(kit.MDB_NAME)) - }}, - }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Fields(len(arg) == 0, "time,name,text") - m.Cmdy(mdb.SELECT, m.Prefix("favor"), "", mdb.HASH, kit.MDB_HASH, arg) - m.Table(func(index int, value map[string]string, head []string) { - m.PushImages("qrcode", kit.MergeURL("https://open.weixin.qq.com/qr/code", aaa.USERNAME, value[kit.MDB_TEXT])) - }) - m.PushAction(mdb.REMOVE) - }}, - "favor2": {Name: "favor name auto create", Help: "收藏", Action: map[string]*ice.Action{ - mdb.CREATE: {Name: "create name link", Help: "添加", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(mdb.INSERT, m.Prefix("favor2"), "", mdb.HASH, arg) - }}, - mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(mdb.DELETE, m.Prefix("favor2"), "", mdb.HASH, kit.MDB_NAME, m.Option(kit.MDB_NAME)) - }}, - }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Fields(len(arg) == 0, "time,name,link") - m.Cmdy(mdb.SELECT, m.Prefix("favor2"), "", mdb.HASH, kit.MDB_HASH, arg) - m.PushAction(mdb.REMOVE) - }}, - - "/login/": {Name: "/login/", Help: "认证", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - check := kit.Sort([]string{m.Conf(LOGIN, kit.Keym(TOKEN)), m.Option("timestamp"), m.Option("nonce")}) - if b := sha1.Sum([]byte(strings.Join(check, ""))); m.Warn(m.Option("signature") != hex.EncodeToString(b[:]), ice.ErrNotRight) { - return // 验证失败 - } - if m.Option("echostr") != "" { - m.Render(ice.RENDER_RESULT, m.Option("echostr")) - return // 绑定验证 - } - - // 解析数据 - _wx_parse(m) - - // 用户登录 - m.Option(ice.MSG_USERZONE, WX) - aaa.UserLogin(m, m.Append("FromUserName"), "") - - switch m.Option("MsgType") { - case kit.MDB_EVENT: - switch m.Option("Event") { - case "subscribe": // 关注事件 - _wx_action(m.Cmdy(MENU, mdb.CREATE)) - case "unsubscribe": // 取关事件 - - case "SCAN": // 扫码 - m.Echo("hello world") - _wx_reply(m, kit.MDB_TEXT) - } - - case kit.MDB_TEXT: - if cmds := kit.Split(m.Option("Content")); m.Warn(!m.Right(cmds), ice.ErrNotRight) { - _wx_action(m.Cmdy(MENU, mdb.CREATE)) - break // 没有权限 - } else { - switch cmds[0] { - case MENU: - // 应用列表 - _wx_action(m.Cmdy(MENU, mdb.CREATE)) - - default: - // 执行命令 - if m.Cmdy(cmds); len(m.Appendv(ice.MSG_APPEND)) == 0 && len(m.Resultv()) == 0 { - m.Cmdy(cli.SYSTEM, cmds) - } else if len(m.Resultv()) == 0 { - m.Table() - } - - // 返回结果 - _wx_reply(m, kit.MDB_TEXT) - } - } - } - }}, }, } func init() { chat.Index.Register(Index, &web.Frame{}) } - -var text = ` - - -{{.Option "CreateTime"}} - - -` diff --git a/misc/wx/wx.shy b/misc/wx/wx.shy index dedf2ce4..3ff9ee5a 100644 --- a/misc/wx/wx.shy +++ b/misc/wx/wx.shy @@ -3,25 +3,24 @@ refer ` 官网 https://weixin.qq.com/ 后台 https://mp.weixin.qq.com/ 文档 https://developers.weixin.qq.com/doc/offiaccount/Getting_Started/Overview.html -源码 https://github.com/shylinux/icebergs/blob/master/misc/wx/wx.go ` qrcode `http://weixin.qq.com/r/_B1-Z7TEXOkjrfAE90jq` chapter "应用" -field favor web.chat.wx.favor -field favor web.chat.wx.favor2 -field scan web.chat.scan -field files web.chat.files -field paste web.chat.paste -field location web.chat.location +field "访问" web.chat.wx.access +field "收藏" web.chat.wx.favor +field "菜单" web.chat.wx.menu + +field "扫码" web.chat.scan +field "复制" web.chat.paste +field "文件" web.chat.files +field "位置" web.chat.location chapter "权限" -field access web.chat.wx.access -field menu web.chat.wx.menu -field share web.share -field sess aaa.sess -field user aaa.user +field "共享" web.share +field "会话" aaa.sess +field "用户" aaa.user chapter "项目" field "趋势图" web.code.git.trend args `icebergs`