diff --git a/go.mod b/go.mod index 69f788413..337aabc8e 100755 --- a/go.mod +++ b/go.mod @@ -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/v2 v2.0.2 github.com/BurntSushi/toml v0.3.1 github.com/PuerkitoBio/goquery v1.5.0 github.com/RichardKnop/machinery v1.6.9 @@ -107,7 +108,6 @@ require ( github.com/unknwon/paginater v0.0.0-20151104151617-7748a72e0141 github.com/urfave/cli v1.22.1 github.com/xanzy/go-gitlab v0.31.0 - github.com/360EntSecGroup-Skylar/excelize/v2 v2.0.2 github.com/yohcop/openid-go v1.0.0 github.com/yuin/goldmark v1.1.27 github.com/yuin/goldmark-meta v0.0.0-20191126180153-f0638e958b60 diff --git a/models/custom_migrations.go b/models/custom_migrations.go index fe40fdf13..d0158530b 100644 --- a/models/custom_migrations.go +++ b/models/custom_migrations.go @@ -22,7 +22,6 @@ var customMigrations = []CustomMigration{ } var customMigrationsStatic = []CustomMigrationStatic{ - {"Alter user static table field type ", alterUserStaticTable}, {"Delete organization user history data ", deleteNotDisplayUser}, {"update issue_fixed_rate to 1 if num_issues is 0 ", updateIssueFixedRate}, } @@ -59,14 +58,6 @@ 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" diff --git a/models/repo_statistic.go b/models/repo_statistic.go index 0b2ded07a..5e872fa38 100755 --- a/models/repo_statistic.go +++ b/models/repo_statistic.go @@ -172,3 +172,10 @@ func UpdateRepoStat(repoStat *RepoStatistic) error { _, err := xStatistic.Exec(sql, repoStat.Impact, repoStat.Completeness, repoStat.Liveness, repoStat.ProjectHealth, repoStat.TeamHealth, repoStat.Growth, repoStat.RadarTotal, repoStat.RepoID, repoStat.Date) return err } + +func UpdateRepoStatVisits(repoStat *RepoStatistic) error { + sql := "update repo_statistic set num_visits=? where repo_id=? and date=?" + + _, err := xStatistic.Exec(sql, repoStat.NumVisits, repoStat.RepoID, repoStat.Date) + return err +} diff --git a/models/user_business_analysis.go b/models/user_business_analysis.go index 502cec806..08be81241 100644 --- a/models/user_business_analysis.go +++ b/models/user_business_analysis.go @@ -153,6 +153,76 @@ func getLastCountDate() int64 { return pageStartTime.Unix() } +func QueryUserStaticDataAll(opts *UserBusinessAnalysisQueryOptions) ([]*UserBusinessAnalysis, int64) { + log.Info("query startTime =" + fmt.Sprint(opts.StartTime) + " endTime=" + fmt.Sprint(opts.EndTime) + " isAll=" + fmt.Sprint(opts.IsAll)) + + statictisSess := xStatistic.NewSession() + defer statictisSess.Close() + + resultMap := make(map[int64]*UserBusinessAnalysis) + + var newAndCond = builder.NewCond() + if len(opts.UserName) > 0 { + newAndCond = newAndCond.And( + builder.Like{"name", opts.UserName}, + ) + } + if !opts.IsAll { + newAndCond = newAndCond.And( + builder.Gte{"count_date": opts.StartTime}, + ) + newAndCond = newAndCond.And( + builder.Lte{"count_date": opts.EndTime}, + ) + } + + allCount, err := statictisSess.Where(newAndCond).Count(new(UserBusinessAnalysis)) + if err != nil { + log.Info("query error." + err.Error()) + return nil, 0 + } + log.Info("query return total:" + fmt.Sprint(allCount)) + pageSize := 200 + totalPage := int(allCount) / pageSize + + for i := 0; i <= int(totalPage); i++ { + userBusinessAnalysisList := make([]*UserBusinessAnalysis, 0) + if err := statictisSess.Table("user_business_analysis").Where(newAndCond).OrderBy("count_date desc").Limit(pageSize, i*pageSize). + Find(&userBusinessAnalysisList); err != nil { + return nil, 0 + } + log.Info("query " + fmt.Sprint(i+1) + " result size=" + fmt.Sprint(len(userBusinessAnalysisList))) + for _, userRecord := range userBusinessAnalysisList { + if _, ok := resultMap[userRecord.ID]; !ok { + resultMap[userRecord.ID] = userRecord + } else { + resultMap[userRecord.ID].CodeMergeCount += userRecord.CodeMergeCount + resultMap[userRecord.ID].CommitCount += userRecord.CommitCount + resultMap[userRecord.ID].IssueCount += userRecord.IssueCount + resultMap[userRecord.ID].CommentCount += userRecord.CommentCount + resultMap[userRecord.ID].FocusRepoCount += userRecord.FocusRepoCount + resultMap[userRecord.ID].StarRepoCount += userRecord.StarRepoCount + resultMap[userRecord.ID].WatchedCount += userRecord.WatchedCount + resultMap[userRecord.ID].CommitCodeSize += userRecord.CommitCodeSize + resultMap[userRecord.ID].CommitDatasetSize += userRecord.CommitDatasetSize + resultMap[userRecord.ID].CommitModelCount += userRecord.CommitModelCount + resultMap[userRecord.ID].SolveIssueCount += userRecord.SolveIssueCount + resultMap[userRecord.ID].EncyclopediasCount += userRecord.EncyclopediasCount + resultMap[userRecord.ID].CreateRepoCount += userRecord.CreateRepoCount + resultMap[userRecord.ID].LoginCount += userRecord.LoginCount + } + } + } + + userBusinessAnalysisReturnList := UserBusinessAnalysisList{} + for _, v := range resultMap { + userBusinessAnalysisReturnList = append(userBusinessAnalysisReturnList, v) + } + sort.Sort(userBusinessAnalysisReturnList) + log.Info("return size=" + fmt.Sprint(len(userBusinessAnalysisReturnList))) + return userBusinessAnalysisReturnList, allCount +} + func QueryUserStaticDataPage(opts *UserBusinessAnalysisQueryOptions) ([]*UserBusinessAnalysis, int64) { log.Info("query startTime =" + fmt.Sprint(opts.StartTime) + " endTime=" + fmt.Sprint(opts.EndTime) + " isAll=" + fmt.Sprint(opts.IsAll)) @@ -219,32 +289,43 @@ func QueryUserStaticDataPage(opts *UserBusinessAnalysisQueryOptions) ([]*UserBus builder.Lte{"count_date": opts.EndTime}, ) } - userBusinessAnalysisList = make([]*UserBusinessAnalysis, 0) - if err := statictisSess.Table("user_business_analysis").Where(newAndCond).OrderBy("count_date desc"). - Find(&userBusinessAnalysisList); err != nil { + + allCount, err := statictisSess.Where(newAndCond).Count(new(UserBusinessAnalysis)) + if err != nil { + log.Info("query error." + err.Error()) return nil, 0 } - } - log.Info("query result size=" + fmt.Sprint(len(userBusinessAnalysisList))) - for _, userRecord := range userBusinessAnalysisList { - if _, ok := resultMap[userRecord.ID]; !ok { - resultMap[userRecord.ID] = userRecord - } else { - resultMap[userRecord.ID].CodeMergeCount += userRecord.CodeMergeCount - resultMap[userRecord.ID].CommitCount += userRecord.CommitCount - resultMap[userRecord.ID].IssueCount += userRecord.IssueCount - resultMap[userRecord.ID].CommentCount += userRecord.CommentCount - resultMap[userRecord.ID].FocusRepoCount += userRecord.FocusRepoCount - resultMap[userRecord.ID].StarRepoCount += userRecord.StarRepoCount - resultMap[userRecord.ID].WatchedCount += userRecord.WatchedCount - resultMap[userRecord.ID].CommitCodeSize += userRecord.CommitCodeSize - resultMap[userRecord.ID].CommitDatasetSize += userRecord.CommitDatasetSize - resultMap[userRecord.ID].CommitModelCount += userRecord.CommitModelCount - resultMap[userRecord.ID].SolveIssueCount += userRecord.SolveIssueCount - resultMap[userRecord.ID].EncyclopediasCount += userRecord.EncyclopediasCount - resultMap[userRecord.ID].CreateRepoCount += userRecord.CreateRepoCount - resultMap[userRecord.ID].LoginCount += userRecord.LoginCount + pageSize := 1000 + totalPage := int(allCount) / pageSize + + for i := 0; i <= int(totalPage); i++ { + userBusinessAnalysisList = make([]*UserBusinessAnalysis, 0) + if err := statictisSess.Table("user_business_analysis").Where(newAndCond).OrderBy("count_date desc").Limit(pageSize, i*pageSize). + Find(&userBusinessAnalysisList); err != nil { + return nil, 0 + } + log.Info("query result size=" + fmt.Sprint(len(userBusinessAnalysisList))) + for _, userRecord := range userBusinessAnalysisList { + if _, ok := resultMap[userRecord.ID]; !ok { + resultMap[userRecord.ID] = userRecord + } else { + resultMap[userRecord.ID].CodeMergeCount += userRecord.CodeMergeCount + resultMap[userRecord.ID].CommitCount += userRecord.CommitCount + resultMap[userRecord.ID].IssueCount += userRecord.IssueCount + resultMap[userRecord.ID].CommentCount += userRecord.CommentCount + resultMap[userRecord.ID].FocusRepoCount += userRecord.FocusRepoCount + resultMap[userRecord.ID].StarRepoCount += userRecord.StarRepoCount + resultMap[userRecord.ID].WatchedCount += userRecord.WatchedCount + resultMap[userRecord.ID].CommitCodeSize += userRecord.CommitCodeSize + resultMap[userRecord.ID].CommitDatasetSize += userRecord.CommitDatasetSize + resultMap[userRecord.ID].CommitModelCount += userRecord.CommitModelCount + resultMap[userRecord.ID].SolveIssueCount += userRecord.SolveIssueCount + resultMap[userRecord.ID].EncyclopediasCount += userRecord.EncyclopediasCount + resultMap[userRecord.ID].CreateRepoCount += userRecord.CreateRepoCount + resultMap[userRecord.ID].LoginCount += userRecord.LoginCount + } + } } } diff --git a/modules/repository/elk_pagedata.go b/modules/repository/elk_pagedata.go index 03a61be1f..1454f0364 100644 --- a/modules/repository/elk_pagedata.go +++ b/modules/repository/elk_pagedata.go @@ -4,6 +4,7 @@ import ( "bytes" "encoding/base64" "encoding/json" + "fmt" "io/ioutil" "net/http" @@ -113,13 +114,23 @@ func GetResultFromElk(resultInfo ResultInfo, jsonStr []byte) (loaded int, totalV client := &http.Client{} resp, err := client.Do(req) if err != nil { - panic(err) + // panic(err) + return 0, 0, err } defer resp.Body.Close() - body, _ := ioutil.ReadAll(resp.Body) - - errs := json.Unmarshal([]byte(string(body)), &resultInfo) - log.Info("Get resultJson failed", errs) + if resp.StatusCode != 200 { + log.Error("ConnectToElk failed:%s", resp.Status) + return 0, 0, fmt.Errorf("ConnectToElk failed:%s", resp.Status) + } + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return 0, 0, err + } + err = json.Unmarshal([]byte(string(body)), &resultInfo) + if err != nil { + log.Error("Get resultJson failed", err) + return 0, 0, err + } return resultInfo.Result.Loaded, resultInfo.Result.RawResponse.Hits.Total, err } @@ -138,6 +149,7 @@ func ProjectViewInit(User string, Project string, Gte string, Lte string) (proje var timeRange Range timeRange.Timestamptest.Gte = Gte timeRange.Timestamptest.Lte = Lte + timeRange.Timestamptest.Format = "strict_date_optional_time" inputStruct.Batch[0].Request.Params.Body.Query.BoolIn.Filter[0].Range = &timeRange //限定用户 var userName FilterMatchPhrase @@ -208,9 +220,10 @@ func TagNameInit(MessageInfo string, Tagname string, Gte string, Lte string) (pr //向elk发送请求,将获取的结果只保留访问量,输入是初始化后的数据结构,返回访问量 func ViewInfo(viewInfo InputInfo) (totalView int, err error) { - jsons, errs := json.Marshal(viewInfo) - if errs != nil { - log.Info("errs:", errs) + jsons, err := json.Marshal(viewInfo) + if err != nil { + log.Error("jsons failed", err) + return 0, err } var jsonStr = []byte(jsons) var resultInfo ResultInfo @@ -221,7 +234,6 @@ func ViewInfo(viewInfo InputInfo) (totalView int, err error) { if loaded == 0 { loaded_next, totalView, err := GetResultFromElk(resultInfo, jsonStr) time++ - log.Info("time:", time) if loaded_next != 0 && time < 100 { return totalView, err } diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini index c2e0aa891..5208eb0eb 100755 --- a/options/locale/locale_zh-CN.ini +++ b/options/locale/locale_zh-CN.ini @@ -816,6 +816,9 @@ total_count_get_error=查询总页数失败。 last_update_time_error=查询最新更新时间失败。 get_repo_stat_error=查询当前仓库的统计信息失败。 get_repo_info_error=查询当前仓库信息失败。 +generate_statistic_file_error=生成文件失败。 +repo_stat_inspect=项目分析 +all=所有 modelarts.status=状态 modelarts.createtime=创建时间 diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index b20713bca..93afe2a31 100755 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -529,6 +529,7 @@ func RegisterRoutes(m *macaron.Macaron) { m.Get("/restoreFork", adminReq, repo.RestoreForkNumber) m.Get("/downloadAll", adminReq, repo.ServeAllProjectsPeriodStatisticsFile) + m.Get("/downloadAllOpenI", adminReq, repo.ServeAllProjectsOpenIStatisticsFile) m.Group("/project", func() { m.Get("", adminReq, repo.GetAllProjectsPeriodStatistics) diff --git a/routers/api/v1/repo/repo_dashbord.go b/routers/api/v1/repo/repo_dashbord.go index 8f7f03533..2926fc4f2 100644 --- a/routers/api/v1/repo/repo_dashbord.go +++ b/routers/api/v1/repo/repo_dashbord.go @@ -207,6 +207,71 @@ func ServeAllProjectsPeriodStatisticsFile(ctx *context.Context) { } +func ServeAllProjectsOpenIStatisticsFile(ctx *context.Context) { + + page := ctx.QueryInt("page") + if page <= 0 { + page = 1 + } + pageSize := 1000 + + _, latestDate, err := models.GetRepoStatLastUpdatedTime() + + if err != nil { + log.Error("Can not query the last updated time.", err) + ctx.Error(http.StatusBadRequest, ctx.Tr("repo.last_update_time_error")) + return + } + + date := ctx.QueryTrim("date") + if date == "" { + date = latestDate + } + + countSql := generateOpenICountSql(date) + total, err := models.CountRepoStatByRawSql(countSql) + if err != nil { + log.Error("Can not query total count.", err) + ctx.Error(http.StatusBadRequest, ctx.Tr("repo.total_count_get_error")) + return + } + var projectAnalysis = ctx.Tr("repo.repo_stat_inspect") + fileName := "项目分析_OPENI_" + date + ".xlsx" + + totalPage := getTotalPage(total, pageSize) + + f := excelize.NewFile() + + index := f.NewSheet(projectAnalysis) + f.DeleteSheet("Sheet1") + + for k, v := range allProjectsOpenIHeader() { + f.SetCellValue(projectAnalysis, k, v) + } + + var row = 2 + for i := 0; i <= totalPage; i++ { + + pageRecords := models.GetRepoStatisticByRawSql(generateTypeAllOpenISql(date, i+1, pageSize)) + for _, record := range pageRecords { + + for k, v := range allProjectsOpenIValues(row, record, ctx) { + f.SetCellValue(projectAnalysis, k, v) + } + row++ + + } + + } + f.SetActiveSheet(index) + + ctx.Resp.Header().Set("Content-Disposition", "attachment; filename="+url.QueryEscape(fileName)) + ctx.Resp.Header().Set("Content-Type", "application/octet-stream") + + f.WriteTo(ctx.Resp) + +} + func getFileName(ctx *context.Context, beginTime time.Time, endTime time.Time, projectAnalysis string) string { baseName := projectAnalysis + "_" @@ -237,6 +302,32 @@ func allProjectsPeroidValues(row int, rs *models.RepoStatistic, ctx *context.Con } } +func allProjectsOpenIHeader() map[string]string { + + return map[string]string{"A1": "ID", "B1": "项目名称", "C1": "拥有者", "D1": "是否私有", "E1": "OpenI指数", + "F1": "影响力", "G1": "成熟度", "H1": "活跃度", "I1": "项目健康度", "J1": "团队健康度", "K1": "项目发展趋势", + "L1": "关注数", "M1": "点赞数", "N1": "派生数", "O1": "代码下载量", "P1": "评论数", "Q1": "浏览量", "R1": "已解决任务数", "S1": "版本发布数量", "T1": "有效开发年龄", + "U1": "数据集", "V1": "模型数", "W1": "百科页面数量", "X1": "提交数", "Y1": "任务数", "Z1": "PR数", "AA1": "版本发布数量", "AB1": "任务完成比例", "AC1": "贡献者数", "AD1": "关键贡献者数", + "AE1": "新人增长量", "AF1": "代码规模增长量", "AG1": "任务增长量", "AH1": "新人增长量", "AI1": "提交增长量", "AJ1": "评论增长量", + } + +} + +func allProjectsOpenIValues(row int, rs *models.RepoStatistic, ctx *context.Context) map[string]string { + + return map[string]string{getCellName("A", row): strconv.FormatInt(rs.RepoID, 10), getCellName("B", row): rs.Name, getCellName("C", row): rs.OwnerName, getCellName("D", row): getIsPrivateDisplay(rs.IsPrivate, ctx), getCellName("E", row): strconv.FormatFloat(rs.RadarTotal, 'f', 2, 64), + getCellName("F", row): strconv.FormatFloat(rs.Impact, 'f', 2, 64), getCellName("G", row): strconv.FormatFloat(rs.Completeness, 'f', 2, 64), getCellName("H", row): strconv.FormatFloat(rs.Liveness, 'f', 2, 64), getCellName("I", row): strconv.FormatFloat(rs.ProjectHealth, 'f', 2, 64), getCellName("J", row): strconv.FormatFloat(rs.TeamHealth, 'f', 2, 64), getCellName("K", row): strconv.FormatFloat(rs.Growth, 'f', 2, 64), + getCellName("L", row): strconv.FormatInt(rs.NumWatches, 10), getCellName("M", row): strconv.FormatInt(rs.NumStars, 10), getCellName("N", row): strconv.FormatInt(rs.NumForks, 10), getCellName("O", row): strconv.FormatInt(rs.NumDownloads, 10), + + getCellName("P", row): strconv.FormatInt(rs.NumComments, 10), getCellName("Q", row): strconv.FormatInt(rs.NumVisits, 10), getCellName("R", row): strconv.FormatInt(rs.NumClosedIssues, 10), getCellName("S", row): strconv.FormatInt(rs.NumVersions, 10), + getCellName("T", row): strconv.FormatInt(rs.NumDevMonths, 10), getCellName("U", row): strconv.FormatInt(rs.DatasetSize, 10), getCellName("V", row): strconv.FormatInt(rs.NumModels, 10), getCellName("W", row): strconv.FormatInt(rs.NumWikiViews, 10), + getCellName("X", row): strconv.FormatInt(rs.NumCommits, 10), getCellName("Y", row): strconv.FormatInt(rs.NumIssues, 10), getCellName("Z", row): strconv.FormatInt(rs.NumPulls, 10), getCellName("AA", row): strconv.FormatInt(rs.NumVersions, 10), + getCellName("AB", row): strconv.FormatFloat(float64(rs.IssueFixedRate), 'f', 2, 64), getCellName("AC", row): strconv.FormatInt(rs.NumContributor, 10), getCellName("AD", row): strconv.FormatInt(rs.NumKeyContributor, 10), getCellName("AE", row): strconv.FormatInt(rs.NumContributorsGrowth, 10), + getCellName("AF", row): strconv.FormatInt(rs.NumCommitLinesGrowth, 10), getCellName("AG", row): strconv.FormatInt(rs.NumIssuesGrowth, 10), getCellName("AH", row): strconv.FormatInt(rs.NumContributorsGrowth, 10), getCellName("AI", row): strconv.FormatInt(rs.NumCommitsGrowth, 10), getCellName("AJ", row): strconv.FormatInt(rs.NumCommentsGrowth, 10), + } + +} + func getCellName(col string, row int) string { return col + strconv.Itoa(row) } @@ -381,6 +472,13 @@ func generateCountSql(beginTime time.Time, endTime time.Time, latestDate string, return countSql } +func generateOpenICountSql(latestDate string) string { + countSql := "SELECT count(*) FROM " + + "public.repo_statistic where date='" + latestDate + "'" + + return countSql +} + func generateTypeAllSql(beginTime time.Time, endTime time.Time, latestDate string, q string, orderBy string, page int, pageSize int) string { sql := "SELECT A.repo_id,name,owner_name,is_private,radar_total,num_watches,num_visits,num_downloads,num_pulls,num_commits,num_stars,num_forks,num_issues,num_closed_issues,num_contributor FROM " + "(SELECT repo_id,sum(num_visits) as num_visits " + @@ -396,6 +494,14 @@ func generateTypeAllSql(beginTime time.Time, endTime time.Time, latestDate strin return sql } +func generateTypeAllOpenISql(latestDate string, page int, pageSize int) string { + sql := "SELECT id, repo_id, date, num_watches, num_stars, num_forks, num_downloads, num_comments, num_visits, num_closed_issues, num_versions, num_dev_months, repo_size, dataset_size, num_models, num_wiki_views, num_commits, num_issues, num_pulls, issue_fixed_rate, num_contributor, num_key_contributor, num_contributors_growth, num_commits_growth, num_commit_lines_growth, num_issues_growth, num_comments_growth, impact, completeness, liveness, project_health, team_health, growth, radar_total, name, is_private, owner_name FROM " + + " public.repo_statistic where date='" + latestDate + "'" + + sql = sql + " order by radar_total desc,repo_id" + " limit " + strconv.Itoa(pageSize) + " offset " + strconv.Itoa((page-1)*pageSize) + return sql +} + func generatePageSql(beginTime time.Time, endTime time.Time, latestDate string, q string, orderBy string, page int, pageSize int) string { sql := "SELECT A.repo_id,name,owner_name,is_private,radar_total,num_watches,num_visits,num_downloads,num_pulls,num_commits,num_stars,num_forks,num_issues,num_closed_issues,num_contributor FROM " + diff --git a/routers/private/internal.go b/routers/private/internal.go index b254d48ba..0dd725ca3 100755 --- a/routers/private/internal.go +++ b/routers/private/internal.go @@ -43,7 +43,8 @@ func RegisterRoutes(m *macaron.Macaron) { m.Post("/manager/restart", Restart) m.Post("/manager/flush-queues", bind(private.FlushOptions{}), FlushQueues) m.Post("/tool/update_all_repo_commit_cnt", UpdateAllRepoCommitCnt) - m.Post("/tool/repo_stat", RepoStatisticManually) + m.Post("/tool/repo_stat/:date", RepoStatisticManually) + m.Post("/tool/update_repo_visit/:date", UpdateRepoVisit) }, CheckInternalToken) } diff --git a/routers/private/tool.go b/routers/private/tool.go index b93f17090..d01c5b2ab 100755 --- a/routers/private/tool.go +++ b/routers/private/tool.go @@ -39,8 +39,35 @@ func UpdateAllRepoCommitCnt(ctx *macaron.Context) { } func RepoStatisticManually(ctx *macaron.Context) { - date := ctx.Query("date") + date := ctx.Params("date") repo.RepoStatisticDaily(date) repo.SummaryStatisticDaily(date) repo.TimingCountDataByDate(date) } + +func UpdateRepoVisit(ctx *macaron.Context) { + date := ctx.Params("date") + log.Info("date(%s)", date) + + repos, err := models.GetAllRepositories() + if err != nil { + log.Error("GetAllRepositories failed:%v", err.Error(), ctx.Data["MsgID"]) + ctx.JSON(http.StatusInternalServerError, map[string]string{ + "error_msg": "GetAllRepositories failed", + }) + return + } + + for i, repoStat := range repos { + log.Info("%d:begin UpdateRepoVisits(id = %d, name = %s)", i, repoStat.ID, repoStat.Name) + if err = repo.UpdateRepoVisits(ctx, repoStat, date); err != nil { + log.Error("UpdateRepoVisits(id = %d, name = %s) failed:%v", repoStat.ID, repoStat.Name, err.Error()) + continue + } + log.Info("%d:finish UpdateRepoVisits(id = %d, name = %s)", i, repoStat.ID, repoStat.Name) + } + + ctx.JSON(http.StatusOK, map[string]string{ + "error_msg": "", + }) +} diff --git a/routers/repo/repo_statistic.go b/routers/repo/repo_statistic.go index 066b29772..7aadd431f 100755 --- a/routers/repo/repo_statistic.go +++ b/routers/repo/repo_statistic.go @@ -1,15 +1,17 @@ package repo import ( + "errors" "time" - "code.gitea.io/gitea/services/mailer" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/normalization" "code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/services/mailer" + + "gitea.com/macaron/macaron" ) func StatisticAuto() { @@ -48,7 +50,7 @@ func RepoStatisticDaily(date string) { var maxRepoRadar models.RepoStatistic for i, repo := range repos { - log.Info("start statistic: %s", repo.Name) + log.Info("start statistic: %s", getDistinctProjectName(repo)) var numDevMonths, numWikiViews, numContributor, numKeyContributor, numCommitsGrowth, numCommitLinesGrowth, numContributorsGrowth int64 repoGitStat, err := models.GetRepoKPIStats(repo) if err != nil { @@ -230,7 +232,7 @@ func RepoStatisticDaily(date string) { } - log.Info("finish statistic: %s", repo.Name) + log.Info("finish statistic: %s", getDistinctProjectName(repo)) } //radar map @@ -274,3 +276,29 @@ func getStatTime(timeStr string) (string, string) { return beginTime, endTime } + +func UpdateRepoVisits(ctx *macaron.Context, repo *models.Repository, date string) error { + beginTime, endTime := getStatTime(date) + var numVisits int + numVisits, err := repository.AppointProjectView(repo.OwnerName, repo.Name, beginTime, endTime) + if err != nil { + log.Error("AppointProjectView failed(%s): %v", getDistinctProjectName(repo), err) + return err + } + + repoStat, err := models.GetRepoStatisticByDate(date, repo.ID) + if err != nil { + log.Error("GetRepoStatisticByDate failed(%s): %v", getDistinctProjectName(repo), err) + return err + } else if len(repoStat) != 1 { + log.Error("GetRepoStatisticByDate failed(%s): %v", getDistinctProjectName(repo), err) + return errors.New("not find repo") + } + repoStat[0].NumVisits = int64(numVisits) + + if err = models.UpdateRepoStatVisits(repoStat[0]); err != nil { + log.Error("UpdateRepoStatVisits failed(%s): %v", getDistinctProjectName(repo), err) + return err + } + return nil +} diff --git a/routers/repo/user_data_analysis.go b/routers/repo/user_data_analysis.go index 5c701eadb..5a6b3d724 100755 --- a/routers/repo/user_data_analysis.go +++ b/routers/repo/user_data_analysis.go @@ -49,13 +49,13 @@ func QueryUserStaticDataPage(ctx *context.Context) { startTime = time.Now() endTime = time.Now() } else { - startTime, _ = time.Parse("2006-01-02", startDate) + startTime, _ = time.ParseInLocation("2006-01-02", startDate, time.Local) settingStartTime, _ := time.Parse("2006-01-02", setting.RadarMap.RecordBeginTime) if startTime.Unix() < settingStartTime.Unix() { startTime = settingStartTime startDate = settingStartTime.Format("2006-01-02") } - endTime, _ = time.Parse("2006-01-02", endDate) + endTime, _ = time.ParseInLocation("2006-01-02", endDate, time.Local) endTime = endTime.AddDate(0, 0, 1) isAll = false log.Info("startTime=" + fmt.Sprint(startTime.Unix()) + " endDate=" + fmt.Sprint(endTime.Unix())) @@ -76,17 +76,15 @@ func QueryUserStaticDataPage(ctx *context.Context) { EndTime: endTime.Unix(), IsAll: isAll, } - mapInterface := make(map[string]interface{}) - re, count := models.QueryUserStaticDataPage(pageOpts) - mapInterface["data"] = re - mapInterface["count"] = count + if IsReturnFile { + re, count := models.QueryUserStaticDataAll(pageOpts) + log.Info("return count=" + fmt.Sprint(count)) //writer exec file. xlsx := excelize.NewFile() - xlsx.DeleteSheet("Sheet1") sheetName := ctx.Tr("user.static.sheetname") index := xlsx.NewSheet(sheetName) - + xlsx.DeleteSheet("Sheet1") dataHeader := map[string]string{ "A1": ctx.Tr("user.static.id"), "B1": ctx.Tr("user.static.name"), @@ -129,8 +127,12 @@ func QueryUserStaticDataPage(ctx *context.Context) { xlsx.SetCellValue(sheetName, "M"+rows, userRecord.EncyclopediasCount) xlsx.SetCellValue(sheetName, "N"+rows, userRecord.CreateRepoCount) xlsx.SetCellValue(sheetName, "O"+rows, fmt.Sprintf("%.2f", userRecord.OpenIIndex)) - xlsx.SetCellValue(sheetName, "P"+rows, userRecord.RegistDate.Format("2006-01-02")) - xlsx.SetCellValue(sheetName, "Q"+rows, time.Unix(userRecord.CountDate, 0).Format("2006-01-02")) + + formatTime := userRecord.RegistDate.Format("2006-01-02 15:04:05") + xlsx.SetCellValue(sheetName, "P"+rows, formatTime[0:len(formatTime)-3]) + + formatTime = time.Unix(userRecord.CountDate, 0).Format("2006-01-02 15:04:05") + xlsx.SetCellValue(sheetName, "Q"+rows, formatTime[0:len(formatTime)-3]) } //设置默认打开的表单 @@ -160,6 +162,10 @@ func QueryUserStaticDataPage(ctx *context.Context) { } } else { + mapInterface := make(map[string]interface{}) + re, count := models.QueryUserStaticDataPage(pageOpts) + mapInterface["data"] = re + mapInterface["count"] = count ctx.JSON(http.StatusOK, mapInterface) } } diff --git a/templates/base/footer_content_fluid.tmpl b/templates/base/footer_content_fluid.tmpl new file mode 100644 index 000000000..e07a4d5ab --- /dev/null +++ b/templates/base/footer_content_fluid.tmpl @@ -0,0 +1,42 @@ + diff --git a/templates/base/footer_fluid.tmpl b/templates/base/footer_fluid.tmpl new file mode 100644 index 000000000..cb3eb7b29 --- /dev/null +++ b/templates/base/footer_fluid.tmpl @@ -0,0 +1,48 @@ +{{/* + +
+