Browse Source

Merge remote-tracking branch 'origin/V20220630' into zouap_static

tags/v1.22.7.1
zouap 3 years ago
parent
commit
b5ede41952
15 changed files with 501 additions and 56 deletions
  1. +2
    -6
      models/custom_migrations.go
  2. +8
    -0
      models/dataset.go
  3. +2
    -7
      models/repo.go
  4. +139
    -0
      modules/auth/wechat/auto_reply.go
  5. +39
    -2
      modules/auth/wechat/client.go
  6. +97
    -4
      modules/auth/wechat/event_handle.go
  7. +13
    -0
      modules/auth/wechat/material.go
  8. +12
    -0
      modules/setting/setting.go
  9. +1
    -1
      options/locale/locale_zh-CN.ini
  10. +23
    -16
      public/home/home.js
  11. +1
    -0
      routers/api/v1/api.go
  12. +22
    -0
      routers/authentication/wechat.go
  13. +129
    -15
      routers/authentication/wechat_event.go
  14. +3
    -1
      routers/home.go
  15. +10
    -4
      routers/repo/dataset.go

+ 2
- 6
models/custom_migrations.go View File

@@ -15,13 +15,9 @@ type CustomMigrationStatic struct {
Migrate func(*xorm.Engine, *xorm.Engine) error Migrate func(*xorm.Engine, *xorm.Engine) error
} }


var customMigrations = []CustomMigration{
{"Custom v1 Topic struct change to support chinese", syncTopicStruct},
}
var customMigrations []CustomMigration


var customMigrationsStatic = []CustomMigrationStatic{
{"update issue_fixed_rate to 1 if num_issues is 0 ", updateIssueFixedRate},
}
var customMigrationsStatic []CustomMigrationStatic


func MigrateCustom(x *xorm.Engine) { func MigrateCustom(x *xorm.Engine) {




+ 8
- 0
models/dataset.go View File

@@ -181,6 +181,7 @@ func SearchDatasetCondition(opts *SearchDatasetOptions) builder.Cond {
if len(opts.DatasetIDs) > 0 { if len(opts.DatasetIDs) > 0 {
subCon := builder.NewCond() subCon := builder.NewCond()
subCon = subCon.And(builder.In("dataset.id", opts.DatasetIDs)) subCon = subCon.And(builder.In("dataset.id", opts.DatasetIDs))
subCon = generateFilterCond(opts, subCon)
cond = cond.Or(subCon) cond = cond.Or(subCon)
} }


@@ -460,5 +461,12 @@ func GetCollaboratorDatasetIdsByUserID(userID int64) []int64 {
_ = x.Table("dataset").Join("INNER", "collaboration", "dataset.repo_id = collaboration.repo_id and collaboration.mode>0 and collaboration.user_id=?", userID). _ = x.Table("dataset").Join("INNER", "collaboration", "dataset.repo_id = collaboration.repo_id and collaboration.mode>0 and collaboration.user_id=?", userID).
Cols("dataset.id").Find(&datasets) Cols("dataset.id").Find(&datasets)
return datasets return datasets
}


func GetTeamDatasetIdsByUserID(userID int64) []int64 {
var datasets []int64
_ = x.Table("dataset").Join("INNER", "team_repo", "dataset.repo_id = team_repo.repo_id").
Join("INNER", "team_user", "team_repo.team_id=team_user.team_id and team_user.uid=?", userID).
Cols("dataset.id").Find(&datasets)
return datasets
} }

+ 2
- 7
models/repo.go View File

@@ -2749,15 +2749,10 @@ func ReadLatestFileInRepo(userName, repoName, refName, treePath string) (*RepoFi
log.Error("ReadLatestFileInRepo: Close: %v", err) log.Error("ReadLatestFileInRepo: Close: %v", err)
} }
}() }()

buf := make([]byte, 1024)
n, _ := reader.Read(buf)
if n >= 0 {
buf = buf[:n]
}
d, _ := ioutil.ReadAll(reader)
commitId := "" commitId := ""
if blob != nil { if blob != nil {
commitId = fmt.Sprint(blob.ID) commitId = fmt.Sprint(blob.ID)
} }
return &RepoFile{CommitId: commitId, Content: buf}, nil
return &RepoFile{CommitId: commitId, Content: d}, nil
} }

+ 139
- 0
modules/auth/wechat/auto_reply.go View File

@@ -0,0 +1,139 @@
package wechat

import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"encoding/json"
"github.com/patrickmn/go-cache"
"strings"
"time"
)

var WechatReplyCache = cache.New(2*time.Minute, 1*time.Minute)

const (
WECHAT_REPLY_CACHE_KEY = "wechat_response"
)

const (
ReplyTypeText = "text"
ReplyTypeImage = "image"
ReplyTypeVoice = "voice"
ReplyTypeVideo = "video"
ReplyTypeMusic = "music"
ReplyTypeNews = "news"
)

type ReplyConfigType string

const (
SubscribeReply ReplyConfigType = "subscribe"
AutoMsgReply ReplyConfigType = "autoMsg"
)

func (r ReplyConfigType) Name() string {
switch r {
case SubscribeReply:
return "subscribe"
case AutoMsgReply:
return "autoMsg"
}
return ""
}

func (r ReplyConfigType) TreePath() string {
switch r {
case SubscribeReply:
return setting.TreePathOfSubscribe
case AutoMsgReply:
return setting.TreePathOfAutoMsgReply
}
return ""
}

type WechatReplyContent struct {
Reply *ReplyContent
ReplyType string
KeyWords []string
IsFullMatch int
}

type ReplyContent struct {
Content string
MediaId string
Title string
Description string
MusicUrl string
HQMusicUrl string
ThumbMediaId string
Articles []ArticlesContent
}

func GetAutomaticReply(msg string) *WechatReplyContent {
r, err := LoadReplyFromCacheAndDisk(AutoMsgReply)
if err != nil {
return nil
}
if r == nil || len(r) == 0 {
return nil
}
for i := 0; i < len(r); i++ {
if r[i].IsFullMatch == 0 {
for _, v := range r[i].KeyWords {
if strings.Contains(msg, v) {
return r[i]
}
}
} else if r[i].IsFullMatch > 0 {
for _, v := range r[i].KeyWords {
if msg == v {
return r[i]
}
}
}
}
return nil

}

func loadReplyFromDisk(replyConfig ReplyConfigType) ([]*WechatReplyContent, error) {
log.Info("LoadReply from disk")
repo, err := models.GetRepositoryByOwnerAndAlias(setting.UserNameOfWechatReply, setting.RepoNameOfWechatReply)
if err != nil {
log.Error("get AutomaticReply repo failed, error=%v", err)
return nil, err
}
repoFile, err := models.ReadLatestFileInRepo(setting.UserNameOfWechatReply, repo.Name, setting.RefNameOfWechatReply, replyConfig.TreePath())
if err != nil {
log.Error("get AutomaticReply failed, error=%v", err)
return nil, err
}
res := make([]*WechatReplyContent, 0)
json.Unmarshal(repoFile.Content, &res)
if res == nil || len(res) == 0 {
return nil, err
}
return res, nil
}

func LoadReplyFromCacheAndDisk(replyConfig ReplyConfigType) ([]*WechatReplyContent, error) {
v, success := WechatReplyCache.Get(replyConfig.Name())
if success {
log.Info("LoadReply from cache,value = %v", v)
if v == nil {
return nil, nil
}
n := v.([]*WechatReplyContent)
return n, nil
}

content, err := loadReplyFromDisk(replyConfig)
if err != nil {
log.Error("LoadReply failed, error=%v", err)
WechatReplyCache.Set(replyConfig.Name(), nil, 30*time.Second)
return nil, err
}
WechatReplyCache.Set(replyConfig.Name(), content, 60*time.Second)
return content, nil
}

+ 39
- 2
modules/auth/wechat/client.go View File

@@ -17,7 +17,8 @@ var (
const ( const (
GRANT_TYPE = "client_credential" GRANT_TYPE = "client_credential"
ACCESS_TOKEN_PATH = "/cgi-bin/token" ACCESS_TOKEN_PATH = "/cgi-bin/token"
QR_CODE_Path = "/cgi-bin/qrcode/create"
QR_CODE_PATH = "/cgi-bin/qrcode/create"
GET_MATERIAL_PATH = "/cgi-bin/material/batchget_material"
ACTION_QR_STR_SCENE = "QR_STR_SCENE" ACTION_QR_STR_SCENE = "QR_STR_SCENE"


ERR_CODE_ACCESSTOKEN_EXPIRE = 42001 ERR_CODE_ACCESSTOKEN_EXPIRE = 42001
@@ -40,6 +41,11 @@ type QRCodeRequest struct {
Action_info ActionInfo `json:"action_info"` Action_info ActionInfo `json:"action_info"`
Expire_seconds int `json:"expire_seconds"` Expire_seconds int `json:"expire_seconds"`
} }
type MaterialRequest struct {
Type string `json:"type"`
Offset int `json:"offset"`
Count int `json:"count"`
}


type ActionInfo struct { type ActionInfo struct {
Scene Scene `json:"scene"` Scene Scene `json:"scene"`
@@ -97,7 +103,7 @@ func callQRCodeCreate(sceneStr string) (*QRCodeResponse, bool) {
SetQueryParam("access_token", GetWechatAccessToken()). SetQueryParam("access_token", GetWechatAccessToken()).
SetBody(bodyJson). SetBody(bodyJson).
SetResult(&result). SetResult(&result).
Post(setting.WechatApiHost + QR_CODE_Path)
Post(setting.WechatApiHost + QR_CODE_PATH)
if err != nil { if err != nil {
log.Error("create QR code failed,e=%v", err) log.Error("create QR code failed,e=%v", err)
return nil, false return nil, false
@@ -113,6 +119,37 @@ func callQRCodeCreate(sceneStr string) (*QRCodeResponse, bool) {
return &result, false return &result, false
} }


//getMaterial
// api doc: https://developers.weixin.qq.com/doc/offiaccount/Asset_Management/Get_materials_list.html
func getMaterial(mType string, offset, count int) (interface{}, bool) {
client := getWechatRestyClient()

body := &MaterialRequest{
Type: mType,
Offset: offset,
Count: count,
}
bodyJson, _ := json.Marshal(body)
r, err := client.R().
SetHeader("Content-Type", "application/json").
SetQueryParam("access_token", GetWechatAccessToken()).
SetBody(bodyJson).
Post(setting.WechatApiHost + GET_MATERIAL_PATH)
if err != nil {
log.Error("create QR code failed,e=%v", err)
return nil, false
}
a := r.Body()
resultMap := make(map[string]interface{}, 0)
json.Unmarshal(a, &resultMap)
errcode := resultMap["errcode"]
if errcode == fmt.Sprint(ERR_CODE_ACCESSTOKEN_EXPIRE) || errcode == fmt.Sprint(ERR_CODE_ACCESSTOKEN_INVALID) {
return nil, true
}
log.Info("%v", r)
return &resultMap, false
}

func getErrorCodeFromResponse(r *resty.Response) int { func getErrorCodeFromResponse(r *resty.Response) int {
a := r.Body() a := r.Body()
resultMap := make(map[string]interface{}, 0) resultMap := make(map[string]interface{}, 0)


+ 97
- 4
modules/auth/wechat/event_handle.go View File

@@ -18,7 +18,7 @@ import (
// <EventKey><![CDATA[SCENE_VALUE]]></EventKey> // <EventKey><![CDATA[SCENE_VALUE]]></EventKey>
// <Ticket><![CDATA[TICKET]]></Ticket> // <Ticket><![CDATA[TICKET]]></Ticket>
//</xml> //</xml>
type WechatEvent struct {
type WechatMsg struct {
ToUserName string ToUserName string
FromUserName string FromUserName string
CreateTime int64 CreateTime int64
@@ -26,9 +26,13 @@ type WechatEvent struct {
Event string Event string
EventKey string EventKey string
Ticket string Ticket string
Content string
MsgId string
MsgDataId string
Idx string
} }


type EventReply struct {
type MsgReply struct {
XMLName xml.Name `xml:"xml"` XMLName xml.Name `xml:"xml"`
ToUserName string ToUserName string
FromUserName string FromUserName string
@@ -37,16 +41,97 @@ type EventReply struct {
Content string Content string
} }


type TextMsgReply struct {
XMLName xml.Name `xml:"xml"`
ToUserName string
FromUserName string
CreateTime int64
MsgType string
Content string
}
type ImageMsgReply struct {
XMLName xml.Name `xml:"xml"`
ToUserName string
FromUserName string
CreateTime int64
MsgType string
Image ImageContent
}
type VoiceMsgReply struct {
XMLName xml.Name `xml:"xml"`
ToUserName string
FromUserName string
CreateTime int64
MsgType string
Voice VoiceContent
}
type VideoMsgReply struct {
XMLName xml.Name `xml:"xml"`
ToUserName string
FromUserName string
CreateTime int64
MsgType string
Video VideoContent
}
type MusicMsgReply struct {
XMLName xml.Name `xml:"xml"`
ToUserName string
FromUserName string
CreateTime int64
MsgType string
Music MusicContent
}
type NewsMsgReply struct {
XMLName xml.Name `xml:"xml"`
ToUserName string
FromUserName string
CreateTime int64
MsgType string
ArticleCount int
Articles ArticleItem
}

type ArticleItem struct {
Item []ArticlesContent
}

type ImageContent struct {
MediaId string
}
type VoiceContent struct {
MediaId string
}
type VideoContent struct {
MediaId string
Title string
Description string
}
type MusicContent struct {
Title string
Description string
MusicUrl string
HQMusicUrl string
ThumbMediaId string
}
type ArticlesContent struct {
XMLName xml.Name `xml:"item"`
Title string
Description string
PicUrl string
Url string
}

const ( const (
WECHAT_EVENT_SUBSCRIBE = "subscribe" WECHAT_EVENT_SUBSCRIBE = "subscribe"
WECHAT_EVENT_SCAN = "SCAN" WECHAT_EVENT_SCAN = "SCAN"
) )


const ( const (
WECHAT_MSG_TYPE_TEXT = "text"
WECHAT_MSG_TYPE_TEXT = "text"
WECHAT_MSG_TYPE_EVENT = "event"
) )


func HandleSubscribeEvent(we WechatEvent) string {
func HandleScanEvent(we WechatMsg) string {
eventKey := we.EventKey eventKey := we.EventKey
if eventKey == "" { if eventKey == "" {
return "" return ""
@@ -74,3 +159,11 @@ func HandleSubscribeEvent(we WechatEvent) string {


return BIND_REPLY_SUCCESS return BIND_REPLY_SUCCESS
} }

func HandleSubscribeEvent(we WechatMsg) *WechatReplyContent {
r, err := LoadReplyFromCacheAndDisk(SubscribeReply)
if err != nil || len(r) == 0 {
return nil
}
return r[0]
}

+ 13
- 0
modules/auth/wechat/material.go View File

@@ -0,0 +1,13 @@
package wechat

import "code.gitea.io/gitea/modules/log"

func GetWechatMaterial(mType string, offset, count int) interface{} {
result, retryFlag := getMaterial(mType, offset, count)
if retryFlag {
log.Info("retryGetWechatMaterial calling")
refreshAccessToken()
result, _ = getMaterial(mType, offset, count)
}
return result
}

+ 12
- 0
modules/setting/setting.go View File

@@ -546,6 +546,13 @@ var (
WechatQRCodeExpireSeconds int WechatQRCodeExpireSeconds int
WechatAuthSwitch bool WechatAuthSwitch bool


//wechat auto reply config
UserNameOfWechatReply string
RepoNameOfWechatReply string
RefNameOfWechatReply string
TreePathOfAutoMsgReply string
TreePathOfSubscribe string

//nginx proxy //nginx proxy
PROXYURL string PROXYURL string
RadarMap = struct { RadarMap = struct {
@@ -1374,6 +1381,11 @@ func NewContext() {
WechatAppSecret = sec.Key("APP_SECRET").MustString("e48e13f315adc32749ddc7057585f198") WechatAppSecret = sec.Key("APP_SECRET").MustString("e48e13f315adc32749ddc7057585f198")
WechatQRCodeExpireSeconds = sec.Key("QR_CODE_EXPIRE_SECONDS").MustInt(120) WechatQRCodeExpireSeconds = sec.Key("QR_CODE_EXPIRE_SECONDS").MustInt(120)
WechatAuthSwitch = sec.Key("AUTH_SWITCH").MustBool(true) WechatAuthSwitch = sec.Key("AUTH_SWITCH").MustBool(true)
UserNameOfWechatReply = sec.Key("AUTO_REPLY_USER_NAME").MustString("OpenIOSSG")
RepoNameOfWechatReply = sec.Key("AUTO_REPLY_REPO_NAME").MustString("promote")
RefNameOfWechatReply = sec.Key("AUTO_REPLY_REF_NAME").MustString("master")
TreePathOfAutoMsgReply = sec.Key("AUTO_REPLY_TREE_PATH").MustString("wechat/auto_reply.json")
TreePathOfSubscribe = sec.Key("SUBSCRIBE_TREE_PATH").MustString("wechat/subscribe_reply.json")


SetRadarMapConfig() SetRadarMapConfig()




+ 1
- 1
options/locale/locale_zh-CN.ini View File

@@ -1423,7 +1423,7 @@ issues.label_templates.helper=选择标签模板
issues.label_templates.use=使用标签集 issues.label_templates.use=使用标签集
issues.label_templates.fail_to_load_file=加载标签模板文件 '%s' 时发生错误:%v issues.label_templates.fail_to_load_file=加载标签模板文件 '%s' 时发生错误:%v
issues.add_label_at=添加了标签 <div class="ui label" style="color: %s\; background-color: %s"> %s </div> %s issues.add_label_at=添加了标签 <div class="ui label" style="color: %s\; background-color: %s"> %s </div> %s
issues.remove_label_at=删除了 <div class="ui label" style="color: %s\; background-color: %s">%s</div> label %s 标签
issues.remove_label_at=删除了标签 <div class="ui label" style="color: %s\; background-color: %s">%s </div> %s
issues.add_milestone_at=` %[2]s 添加了里程碑 <b>%[1]s</b>` issues.add_milestone_at=` %[2]s 添加了里程碑 <b>%[1]s</b>`
issues.change_milestone_at=`%[3]s 修改了里程碑从 <b>%[1]s</b> 到 <b>%[2]s</b>` issues.change_milestone_at=`%[3]s 修改了里程碑从 <b>%[1]s</b> 到 <b>%[2]s</b>`
issues.remove_milestone_at=`%[2]s 删除了里程碑 <b>%[1]s</b>` issues.remove_milestone_at=`%[2]s 删除了里程碑 <b>%[1]s</b>`


+ 23
- 16
public/home/home.js View File

@@ -74,28 +74,30 @@ var swiperOrg = new Swiper(".homeorg-list", {
}, },
}); });


var output = document.getElementById("newmessage");
var url = "ws://" + document.location.host + "/action/notification";
if(document.location.host == "git.openi.org.cn" || document.URL.startsWith("https")){
url = "wss://" + document.location.host + "/action/notification"
}
var socket = new WebSocket(url);

socket.onopen = function () {
messageQueue = [];
console.log("message has connected.");
};

var maxSize = 20; var maxSize = 20;
var html =document.documentElement; var html =document.documentElement;
var lang = html.attributes["lang"] var lang = html.attributes["lang"]
var isZh = true; var isZh = true;
if(lang != null && lang.nodeValue =="en-US" ){ if(lang != null && lang.nodeValue =="en-US" ){
isZh=false; isZh=false;
}else{
} }


socket.onmessage = function (e) {
document.onreadystatechange = function () {
queryRecommendData();

var output = document.getElementById("newmessage");
var url = "ws://" + document.location.host + "/action/notification";
if(document.location.host == "git.openi.org.cn" || document.URL.startsWith("https")){
url = "wss://" + document.location.host + "/action/notification"
}
var socket = new WebSocket(url);
socket.onopen = function () {
messageQueue = [];
console.log("message has connected.");
};

socket.onmessage = function (e) {
var data =JSON.parse(e.data) var data =JSON.parse(e.data)
var html = ""; var html = "";
if (data != null){ if (data != null){
@@ -176,7 +178,10 @@ socket.onmessage = function (e) {
output.innerHTML = html; output.innerHTML = html;
swiperNewMessage.updateSlides(); swiperNewMessage.updateSlides();
swiperNewMessage.updateProgress(); swiperNewMessage.updateProgress();
};
};
}




function getTaskLink(record){ function getTaskLink(record){
var re = getRepoLink(record); var re = getRepoLink(record);
@@ -437,7 +442,9 @@ function getAction(opType,isZh){
} }
} }


queryRecommendData();





function queryRecommendData(){ function queryRecommendData(){
$.ajax({ $.ajax({


+ 1
- 0
routers/api/v1/api.go View File

@@ -1052,6 +1052,7 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Get("/prd/event", authentication.ValidEventSource) m.Get("/prd/event", authentication.ValidEventSource)
m.Post("/prd/event", authentication.AcceptWechatEvent) m.Post("/prd/event", authentication.AcceptWechatEvent)
}) })
m.Get("/wechat/material", authentication.GetMaterial)
}, securityHeaders(), context.APIContexter(), sudo()) }, securityHeaders(), context.APIContexter(), sudo())
} }




+ 22
- 0
routers/authentication/wechat.go View File

@@ -8,9 +8,11 @@ import (
"code.gitea.io/gitea/modules/redis/redis_client" "code.gitea.io/gitea/modules/redis/redis_client"
"code.gitea.io/gitea/modules/redis/redis_key" "code.gitea.io/gitea/modules/redis/redis_key"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/routers/response"
"encoding/json" "encoding/json"
"errors" "errors"
gouuid "github.com/satori/go.uuid" gouuid "github.com/satori/go.uuid"
"strconv"
"time" "time"
) )


@@ -124,3 +126,23 @@ func createQRCode4Bind(userId int64) (*QRCodeResponse, error) {
} }
return result, nil return result, nil
} }

// GetMaterial
func GetMaterial(ctx *context.Context) {
mType := ctx.Query("type")
offsetStr := ctx.Query("offset")
countStr := ctx.Query("count")
var offset, count int
if offsetStr == "" {
offset = 0
} else {
offset, _ = strconv.Atoi(offsetStr)
}
if countStr == "" {
count = 20
} else {
count, _ = strconv.Atoi(countStr)
}
r := wechat.GetWechatMaterial(mType, offset, count)
ctx.JSON(200, response.SuccessWithData(r))
}

+ 129
- 15
routers/authentication/wechat_event.go View File

@@ -14,24 +14,48 @@ import (
// https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Passive_user_reply_message.html // https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Passive_user_reply_message.html
func AcceptWechatEvent(ctx *context.Context) { func AcceptWechatEvent(ctx *context.Context) {
b, _ := ioutil.ReadAll(ctx.Req.Request.Body) b, _ := ioutil.ReadAll(ctx.Req.Request.Body)
we := wechat.WechatEvent{}
we := wechat.WechatMsg{}
xml.Unmarshal(b, &we) xml.Unmarshal(b, &we)

switch we.MsgType {
case wechat.WECHAT_MSG_TYPE_EVENT:
HandleEventMsg(ctx, we)
case wechat.WECHAT_MSG_TYPE_TEXT:
HandleTextMsg(ctx, we)
}
log.Info("accept wechat event= %+v", we) log.Info("accept wechat event= %+v", we)
var replyStr string
switch we.Event {
case wechat.WECHAT_EVENT_SUBSCRIBE, wechat.WECHAT_EVENT_SCAN:
replyStr = wechat.HandleSubscribeEvent(we)
break

}

// ValidEventSource
func ValidEventSource(ctx *context.Context) {
echostr := ctx.Query("echostr")
ctx.Write([]byte(echostr))
return
}

func HandleEventMsg(ctx *context.Context, msg wechat.WechatMsg) {
switch msg.Event {
case wechat.WECHAT_EVENT_SCAN:
HandleEventScan(ctx, msg)
case wechat.WECHAT_EVENT_SUBSCRIBE:
if msg.EventKey != "" {
HandleEventScan(ctx, msg)
} else {
HandleEventSubscribe(ctx, msg)
}

} }
}


func HandleEventScan(ctx *context.Context, msg wechat.WechatMsg) {
replyStr := wechat.HandleScanEvent(msg)
if replyStr == "" { if replyStr == "" {
log.Info("reply str is empty") log.Info("reply str is empty")
return return
} }
reply := &wechat.EventReply{
ToUserName: we.FromUserName,
FromUserName: we.ToUserName,
reply := &wechat.MsgReply{
ToUserName: msg.FromUserName,
FromUserName: msg.ToUserName,
CreateTime: time.Now().Unix(), CreateTime: time.Now().Unix(),
MsgType: wechat.WECHAT_MSG_TYPE_TEXT, MsgType: wechat.WECHAT_MSG_TYPE_TEXT,
Content: replyStr, Content: replyStr,
@@ -39,9 +63,99 @@ func AcceptWechatEvent(ctx *context.Context) {
ctx.XML(200, reply) ctx.XML(200, reply)
} }


// ValidEventSource
func ValidEventSource(ctx *context.Context) {
echostr := ctx.Query("echostr")
ctx.Write([]byte(echostr))
return
func HandleEventSubscribe(ctx *context.Context, msg wechat.WechatMsg) {
r := wechat.HandleSubscribeEvent(msg)
if r == nil {
return
}
reply := buildReplyContent(msg, r)
ctx.XML(200, reply)
}

func HandleTextMsg(ctx *context.Context, msg wechat.WechatMsg) {
r := wechat.GetAutomaticReply(msg.Content)
if r == nil {
log.Info("TextMsg reply is empty")
return
}
reply := buildReplyContent(msg, r)
ctx.XML(200, reply)
}

func buildReplyContent(msg wechat.WechatMsg, r *wechat.WechatReplyContent) interface{} {
reply := &wechat.MsgReply{
ToUserName: msg.FromUserName,
FromUserName: msg.ToUserName,
CreateTime: time.Now().Unix(),
MsgType: r.ReplyType,
}
switch r.ReplyType {
case wechat.ReplyTypeText:
return &wechat.TextMsgReply{
ToUserName: msg.FromUserName,
FromUserName: msg.ToUserName,
CreateTime: time.Now().Unix(),
MsgType: r.ReplyType,
Content: r.Reply.Content,
}

case wechat.ReplyTypeImage:
return &wechat.ImageMsgReply{
ToUserName: msg.FromUserName,
FromUserName: msg.ToUserName,
CreateTime: time.Now().Unix(),
MsgType: r.ReplyType,
Image: wechat.ImageContent{
MediaId: r.Reply.MediaId,
},
}
case wechat.ReplyTypeVoice:
return &wechat.VoiceMsgReply{
ToUserName: msg.FromUserName,
FromUserName: msg.ToUserName,
CreateTime: time.Now().Unix(),
MsgType: r.ReplyType,
Voice: wechat.VoiceContent{
MediaId: r.Reply.MediaId,
},
}
case wechat.ReplyTypeVideo:
return &wechat.VideoMsgReply{
ToUserName: msg.FromUserName,
FromUserName: msg.ToUserName,
CreateTime: time.Now().Unix(),
MsgType: r.ReplyType,
Video: wechat.VideoContent{
MediaId: r.Reply.MediaId,
Title: r.Reply.Title,
Description: r.Reply.Description,
},
}
case wechat.ReplyTypeMusic:
return &wechat.MusicMsgReply{
ToUserName: msg.FromUserName,
FromUserName: msg.ToUserName,
CreateTime: time.Now().Unix(),
MsgType: r.ReplyType,
Music: wechat.MusicContent{
Title: r.Reply.Title,
Description: r.Reply.Description,
MusicUrl: r.Reply.MusicUrl,
HQMusicUrl: r.Reply.HQMusicUrl,
ThumbMediaId: r.Reply.ThumbMediaId,
},
}
case wechat.ReplyTypeNews:
return &wechat.NewsMsgReply{
ToUserName: msg.FromUserName,
FromUserName: msg.ToUserName,
CreateTime: time.Now().Unix(),
MsgType: r.ReplyType,
ArticleCount: len(r.Reply.Articles),
Articles: wechat.ArticleItem{
Item: r.Reply.Articles},
}

}
return reply
} }

+ 3
- 1
routers/home.go View File

@@ -345,7 +345,9 @@ func ExploreDatasets(ctx *context.Context) {
var datasetsIds []int64 var datasetsIds []int64
if ownerID > 0 { if ownerID > 0 {


datasetsIds = models.GetCollaboratorDatasetIdsByUserID(ownerID)
collaboratorDatasetsIds := models.GetCollaboratorDatasetIdsByUserID(ownerID)
teamDatasetsIds := models.GetTeamDatasetIdsByUserID(ownerID)
datasetsIds = append(collaboratorDatasetsIds, teamDatasetsIds...)
} }


opts := &models.SearchDatasetOptions{ opts := &models.SearchDatasetOptions{


+ 10
- 4
routers/repo/dataset.go View File

@@ -172,8 +172,8 @@ func DatasetIndex(ctx *context.Context) {
for _, attachment := range pageAttachments { for _, attachment := range pageAttachments {
uploader, _ := models.GetUserByID(attachment.UploaderID) uploader, _ := models.GetUserByID(attachment.UploaderID)
attachment.Uploader = uploader attachment.Uploader = uploader
if !strings.HasSuffix(attachment.Name, ".zip") {
attachment.DecompressState = -1 //非zip文件
if !strings.HasSuffix(attachment.Name, ".zip") && !strings.HasSuffix(attachment.Name, ".tar.gz") {
attachment.DecompressState = -1 //非压缩文件
} }


} }
@@ -616,8 +616,14 @@ func DatasetIsCollaborator(ctx *context.Context, dataset *models.Dataset) bool {
repo.GetOwner() repo.GetOwner()
if ctx.User != nil { if ctx.User != nil {
if repo.Owner.IsOrganization() { if repo.Owner.IsOrganization() {
if repo.Owner.IsUserPartOfOrg(ctx.User.ID) {
for _, t := range repo.Owner.Teams {
org := repo.Owner
org.Teams, err = org.GetUserTeams(ctx.User.ID)
if err != nil {
log.Error("GetUserTeams error:", err.Error())
return false
}
if org.IsUserPartOfOrg(ctx.User.ID) {
for _, t := range org.Teams {
if t.IsMember(ctx.User.ID) && t.HasRepository(repo.ID) { if t.IsMember(ctx.User.ID) && t.HasRepository(repo.ID) {
return true return true
} }


Loading…
Cancel
Save