Browse Source

提交代码。

Signed-off-by: zouap <zouap@pcl.ac.cn>
pull/1036/head
zouap 3 years ago
parent
commit
0d7d6b59a4
6 changed files with 139 additions and 29 deletions
  1. +1
    -0
      go.mod
  2. +5
    -0
      go.sum
  3. +11
    -3
      models/custom_migrations.go
  4. +42
    -16
      models/user_business_analysis.go
  5. +78
    -8
      routers/repo/user_data_analysis.go
  6. +2
    -2
      routers/routes/routes.go

+ 1
- 0
go.mod View File

@@ -17,6 +17,7 @@ require (
gitea.com/macaron/macaron v1.4.0
gitea.com/macaron/session v0.0.0-20191207215012-613cebf0674d
gitea.com/macaron/toolbox v0.0.0-20190822013122-05ff0fc766b7
github.com/360EntSecGroup-Skylar/excelize v1.4.1 // indirect
github.com/BurntSushi/toml v0.3.1
github.com/PuerkitoBio/goquery v1.5.0
github.com/RichardKnop/machinery v1.6.9


+ 5
- 0
go.sum View File

@@ -51,6 +51,8 @@ gitea.com/macaron/toolbox v0.0.0-20190822013122-05ff0fc766b7 h1:N9QFoeNsUXLhl14m
gitea.com/macaron/toolbox v0.0.0-20190822013122-05ff0fc766b7/go.mod h1:kgsbFPPS4P+acDYDOPDa3N4IWWOuDJt5/INKRUz7aks=
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s=
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU=
github.com/360EntSecGroup-Skylar/excelize v1.4.1 h1:l55mJb6rkkaUzOpSsgEeKYtS6/0gHwBYyfo5Jcjv/Ks=
github.com/360EntSecGroup-Skylar/excelize v1.4.1/go.mod h1:vnax29X2usfl7HHkBrX5EvSCJcmH3dT9luvxzu8iGAE=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
@@ -538,6 +540,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
github.com/mrjones/oauth v0.0.0-20180629183705-f4e24b6d100c h1:3wkDRdxK92dF+c1ke2dtj7ZzemFWBHB9plnJOtlwdFA=
github.com/mrjones/oauth v0.0.0-20180629183705-f4e24b6d100c/go.mod h1:skjdDftzkFALcuGzYSklqYd8gvat6F1gZJ4YPVbkZpM=
github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae h1:VeRdUYdCw49yizlSbMEn2SZ+gT+3IUKx8BqxyQdz+BY=
@@ -713,6 +717,7 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.2.3-0.20181224173747-660f15d67dbb/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=


+ 11
- 3
models/custom_migrations.go View File

@@ -22,6 +22,7 @@ var customMigrations = []CustomMigration{
}

var customMigrationsStatic = []CustomMigrationStatic{
{"Alter user static table field type open_i_index ", alterUserStaticTable},
{"Delete zuzhi user history data ", deleteNotDisplayUser},
}

@@ -57,10 +58,17 @@ func syncTopicStruct(x *xorm.Engine) error {
return err
}

func alterUserStaticTable(x *xorm.Engine, static *xorm.Engine) error {
alterSql := "alter table public.user_business_analysis alter column open_i_index type double precision"

_, err := static.Exec(alterSql)
return err

}

func deleteNotDisplayUser(x *xorm.Engine, static *xorm.Engine) error {

querySQL := "select id,name from public.user where type=1"

rows, err := x.Query(querySQL)
if err != nil {
log.Info("select db failed,err:", err)
@@ -68,8 +76,8 @@ func deleteNotDisplayUser(x *xorm.Engine, static *xorm.Engine) error {
}

for i, userRow := range rows {
log.Info("delete zuzi user, i=" + fmt.Sprint(i) + " userName=" + string(userRow["id"]))
deleteSql := "delete from user_business_analysis where id=" + string(userRow["id"]) + " and name='" + string(userRow["name"]) + "'"
log.Info("delete zuzi user, i=" + fmt.Sprint(i) + " userName=" + string(userRow["name"]))
deleteSql := "delete from public.user_business_analysis where id=" + string(userRow["id"]) + " and name='" + string(userRow["name"]) + "'"
static.Exec(deleteSql)
}



+ 42
- 16
models/user_business_analysis.go View File

@@ -3,6 +3,7 @@ package models
import (
"encoding/json"
"fmt"
"sort"
"time"

"code.gitea.io/gitea/modules/log"
@@ -65,13 +66,15 @@ type UserBusinessAnalysis struct {
LoginCount int `xorm:"NOT NULL DEFAULT 0"`

//openi index
OpenIIndex int `xorm:"NOT NULL DEFAULT 0"`
OpenIIndex float64 `xorm:"NOT NULL DEFAULT 0"`

//user
Email string `xorm:"NOT NULL"`

//user
Name string `xorm:"NOT NULL"`

DataDate string `xorm:"NOT NULL"`
}

type UserBusinessAnalysisQueryOptions struct {
@@ -82,6 +85,22 @@ type UserBusinessAnalysisQueryOptions struct {
EndTime int64
}

type UserBusinessAnalysisList []*UserBusinessAnalysis

func (ulist UserBusinessAnalysisList) Swap(i, j int) { ulist[i], ulist[j] = ulist[j], ulist[i] }
func (ulist UserBusinessAnalysisList) Len() int { return len(ulist) }
func (ulist UserBusinessAnalysisList) Less(i, j int) bool {
if ulist[i].CommitCount > ulist[j].CommitCount {
return true
} else {
if ulist[i].CommitCount == ulist[j].CommitCount {
return ulist[i].ID > ulist[j].ID
} else {
return false
}
}
}

func QueryUserStaticData(startTime int64, endTime int64) []*UserBusinessAnalysis {
log.Info("query startTime =" + fmt.Sprint(startTime) + " endTime=" + fmt.Sprint(endTime))
statictisSess := xStatistic.NewSession()
@@ -115,12 +134,11 @@ func QueryUserStaticData(startTime int64, endTime int64) []*UserBusinessAnalysis
}
}

userBusinessAnalysisReturnList := make([]*UserBusinessAnalysis, len(resultMap))
index := 0
userBusinessAnalysisReturnList := UserBusinessAnalysisList{}
for _, v := range resultMap {
userBusinessAnalysisReturnList[index] = v
index += 1
userBusinessAnalysisReturnList = append(userBusinessAnalysisReturnList, v)
}
sort.Sort(userBusinessAnalysisReturnList)
log.Info("return size=" + fmt.Sprint(len(userBusinessAnalysisReturnList)))
return userBusinessAnalysisReturnList
}
@@ -138,7 +156,7 @@ func QueryUserStaticDataPage(opts *UserBusinessAnalysisQueryOptions) ([]*UserBus
var cond = builder.NewCond()
if len(opts.UserName) > 0 {
cond = cond.And(
builder.Eq{"name": opts.UserName},
builder.Like{"name", opts.UserName},
)
}
cond = cond.And(
@@ -218,17 +236,17 @@ func QueryUserStaticDataPage(opts *UserBusinessAnalysisQueryOptions) ([]*UserBus
}
}

userBusinessAnalysisReturnList := make([]*UserBusinessAnalysis, len(resultMap))
index := 0
userBusinessAnalysisReturnList := UserBusinessAnalysisList{}
for _, v := range resultMap {
userBusinessAnalysisReturnList[index] = v
index += 1
userBusinessAnalysisReturnList = append(userBusinessAnalysisReturnList, v)
}
sort.Sort(userBusinessAnalysisReturnList)
log.Info("return size=" + fmt.Sprint(len(userBusinessAnalysisReturnList)))
return userBusinessAnalysisReturnList, count
}

func CounDataByDate(wikiCountMap map[string]int, startTime time.Time, endTime time.Time) {
func CounDataByDateAndReCount(wikiCountMap map[string]int, startTime time.Time, endTime time.Time, isReCount bool) {

log.Info("start to count other user info data")
sess := x.NewSession()
defer sess.Close()
@@ -246,9 +264,12 @@ func CounDataByDate(wikiCountMap map[string]int, startTime time.Time, endTime ti

//endTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 0, 0, 0, 0, currentTimeNow.Location())
end_unix := endTime.Unix()

CountDate := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 0, 1, 0, 0, currentTimeNow.Location())
if isReCount {
CountDate = time.Date(startTime.Year(), startTime.Month(), startTime.Day(), 0, 1, 0, 0, startTime.Location())
}

DataDate := startTime.Format("2006-01-02")
CodeMergeCountMap := queryPullRequest(start_unix, end_unix)
CommitCountMap := queryAction(start_unix, end_unix, 5)
IssueCountMap := queryAction(start_unix, end_unix, 10)
@@ -285,6 +306,7 @@ func CounDataByDate(wikiCountMap map[string]int, startTime time.Time, endTime ti
dateRecord.RegistDate = userRecord.CreatedUnix
dateRecord.Name = userRecord.Name
dateRecord.GiteaAgeMonth = subMonth(currentTimeNow, userRecord.CreatedUnix.AsTime())
dateRecord.DataDate = DataDate
if _, ok := CodeMergeCountMap[dateRecord.ID]; !ok {
dateRecord.CodeMergeCount = 0
} else {
@@ -366,7 +388,7 @@ func CounDataByDate(wikiCountMap map[string]int, startTime time.Time, endTime ti
if _, ok := OpenIIndexMap[dateRecord.ID]; !ok {
dateRecord.OpenIIndex = 0
} else {
dateRecord.OpenIIndex = int(OpenIIndexMap[dateRecord.ID] * 100)
dateRecord.OpenIIndex = OpenIIndexMap[dateRecord.ID]
}

dateRecord.CommitModelCount = 0
@@ -376,6 +398,10 @@ func CounDataByDate(wikiCountMap map[string]int, startTime time.Time, endTime ti

}

func CounDataByDate(wikiCountMap map[string]int, startTime time.Time, endTime time.Time) {
CounDataByDateAndReCount(wikiCountMap, startTime, endTime, false)
}

func querySolveIssue(start_unix int64, end_unix int64) map[int64]int {
//select issue_assignees.* from issue_assignees,issue where issue.is_closed=true and issue.id=issue_assignees.issue_id
sess := x.NewSession()
@@ -507,10 +533,10 @@ func queryFollow(start_unix int64, end_unix int64) map[int64]int {
resultMap := make(map[int64]int)
log.Info("query Follow size=" + fmt.Sprint(len(followList)))
for _, followRecord := range followList {
if _, ok := resultMap[followRecord.UserID]; !ok {
resultMap[followRecord.UserID] = 1
if _, ok := resultMap[followRecord.FollowID]; !ok {
resultMap[followRecord.FollowID] = 1
} else {
resultMap[followRecord.UserID] += 1
resultMap[followRecord.FollowID] += 1
}
}
return resultMap


+ 78
- 8
routers/repo/user_data_analysis.go View File

@@ -10,6 +10,7 @@ import (
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"github.com/360EntSecGroup-Skylar/excelize"
)

func QueryUserStaticData(ctx *context.Context) {
@@ -18,6 +19,7 @@ func QueryUserStaticData(ctx *context.Context) {
log.Info("startDate=" + startDate + " endDate=" + endDate)
startTime, _ := time.Parse("2006-01-02", startDate)
endTime, _ := time.Parse("2006-01-02", endDate)
endTime = endTime.AddDate(0, 0, 1)
log.Info("startTime=" + fmt.Sprint(startTime.Unix()) + " endDate=" + fmt.Sprint(endTime.Unix()))
ctx.JSON(http.StatusOK, models.QueryUserStaticData(startTime.Unix(), endTime.Unix()))
}
@@ -29,17 +31,24 @@ func QueryUserStaticDataPage(ctx *context.Context) {
if page <= 0 {
page = 1
}
pageSize := ctx.QueryInt("pageSize")
if pageSize <= 0 {
pageSize = setting.UI.IssuePagingNum
}
userName := ctx.Query("userName")

IsReturnFile := ctx.QueryBool("IsReturnFile")

log.Info("startDate=" + startDate + " endDate=" + endDate + " userName=" + userName + " page=" + fmt.Sprint(page))
startTime, _ := time.Parse("2006-01-02", startDate)
endTime, _ := time.Parse("2006-01-02", endDate)
endTime = endTime.AddDate(0, 0, 1)
log.Info("startTime=" + fmt.Sprint(startTime.Unix()) + " endDate=" + fmt.Sprint(endTime.Unix()))

pageOpts := &models.UserBusinessAnalysisQueryOptions{
ListOptions: models.ListOptions{
Page: page,
PageSize: setting.UI.IssuePagingNum,
PageSize: pageSize,
},
UserName: userName,
StartTime: startTime.Unix(),
@@ -49,11 +58,71 @@ func QueryUserStaticDataPage(ctx *context.Context) {
re, count := models.QueryUserStaticDataPage(pageOpts)
mapInterface["data"] = re
mapInterface["count"] = count
ctx.JSON(http.StatusOK, mapInterface)
}

func TimingCountDataByDate(date string) {
if IsReturnFile {
//writer exec file.
xlsx := excelize.NewFile()
sheetName := "用户分析"
index := xlsx.NewSheet(sheetName)
dataHeader := map[string]string{
//学科
"A1": "ID",
"B1": "用户名",
"C1": "PR数",
"D1": "提出任务数",
"E1": "评论数",
"F1": "关注项目数",
"G1": "点赞项目数",
"H1": "登录次数",
"I1": "关注者数",
"J1": "commit代码行数",
"K1": "已解决任务数",
"L1": "百科页面贡献次数",
"M1": "创建项目",
"N1": "OpenI指数",
"O1": "用户注册时间",
"P1": "系统统计时间",
}
for k, v := range dataHeader {
//设置单元格的值
xlsx.SetCellValue(sheetName, k, v)
}

for i, userRecord := range re {
rows := fmt.Sprint(i + 2)

xlsx.SetCellValue(sheetName, "A"+rows, userRecord.ID)
xlsx.SetCellValue(sheetName, "B"+rows, userRecord.Name)
xlsx.SetCellValue(sheetName, "C"+rows, userRecord.CodeMergeCount)
xlsx.SetCellValue(sheetName, "D"+rows, userRecord.IssueCount)
xlsx.SetCellValue(sheetName, "E"+rows, userRecord.CommentCount)
xlsx.SetCellValue(sheetName, "F"+rows, userRecord.FocusRepoCount)
xlsx.SetCellValue(sheetName, "G"+rows, userRecord.StarRepoCount)
xlsx.SetCellValue(sheetName, "H"+rows, userRecord.LoginCount)
xlsx.SetCellValue(sheetName, "I"+rows, userRecord.WatchedCount)
xlsx.SetCellValue(sheetName, "J"+rows, userRecord.CommitCodeSize)
xlsx.SetCellValue(sheetName, "K"+rows, userRecord.SolveIssueCount)
xlsx.SetCellValue(sheetName, "L"+rows, userRecord.EncyclopediasCount)
xlsx.SetCellValue(sheetName, "M"+rows, userRecord.CreateRepoCount)
xlsx.SetCellValue(sheetName, "N"+rows, userRecord.OpenIIndex)
xlsx.SetCellValue(sheetName, "O"+rows, userRecord.RegistDate.Format("2006-01-02"))
xlsx.SetCellValue(sheetName, "P"+rows, time.Unix(userRecord.CountDate, 0).Format("2006-01-02"))
}

//设置默认打开的表单
xlsx.SetActiveSheet(index)

err := xlsx.SaveAs("./成绩表.xlsx")
if err != nil {
log.Error(err)
}

} else {
ctx.JSON(http.StatusOK, mapInterface)
}
}

func TimingCountDataByDateAndReCount(date string, isReCount bool) {
t, _ := time.Parse("2006-01-02", date)
startTime := time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location())

@@ -100,16 +169,17 @@ func TimingCountDataByDate(date string) {
}
}
//other user info data
models.CounDataByDate(wikiMap, startTime, endTime)
models.CounDataByDateAndReCount(wikiMap, startTime, endTime, isReCount)
}

func TimingCountDataByDate(date string) {
TimingCountDataByDateAndReCount(date, true)
}

func TimingCountData() {

log.Info("start to time count data")
currentTimeNow := time.Now()
log.Info("current time:" + currentTimeNow.Format("2006-01-02 15:04:05"))
startTime := currentTimeNow.AddDate(0, 0, -1).Format("2006-01-02")

TimingCountDataByDate(startTime)
TimingCountDataByDateAndReCount(startTime, false)
}

+ 2
- 2
routers/routes/routes.go View File

@@ -792,8 +792,8 @@ func RegisterRoutes(m *macaron.Macaron) {
}, reqSignIn, context.RepoAssignment(), context.UnitTypes(), reqRepoAdmin, context.RepoRef())

m.Post("/:username/:reponame/action/:action", reqSignIn, context.RepoAssignment(), context.UnitTypes(), repo.Action)
m.Get("/tool/query_user_static", repo.QueryUserStaticData)
m.Get("/tool/query_user_static_page", repo.QueryUserStaticDataPage)
m.Get("/tool/query_user_static", adminReq, repo.QueryUserStaticData)
m.Get("/tool/query_user_static_page", adminReq, repo.QueryUserStaticDataPage)
// Grouping for those endpoints not requiring authentication
m.Group("/:username/:reponame", func() {
m.Get("/contributors", repo.Contributors)


Loading…
Cancel
Save