"
+ html += "
" + record.ActUser.Name + ""
+ return html;
+}
+
+function getRepoLink(record){
+ return "/" + record.Repo.OwnerName + "/" + record.Repo.Name;
+}
+function getRepoLink(record){
+ return record.Repo.OwnerName + "/" + record.Repo.Name;
+}
+
+function getTime(UpdatedUnix,currentTime){
+ UpdatedUnix = UpdatedUnix;
+ currentTime = currentTime / 1000;
+ var timeEscSecond = currentTime - UpdatedUnix;
+ if( timeEscSecond < 0){
+ timeEscSecond = 1;
+ }
+ console.log("currentTime=" + currentTime + " updateUnix=" + UpdatedUnix);
+
+ var hours= Math.floor(timeEscSecond / 3600);
+ //计算相差分钟数
+ var leave2 = Math.floor(timeEscSecond % (3600)); //计算小时数后剩余的秒数
+ var minutes= Math.floor(leave2 / 60);//计算相差分钟数
+
+ var leave3=Math.floor(leave2 % 60); //计算分钟数后剩余的秒数
+ var seconds= leave3;
+
+ if(hours == 0 && minutes == 0){
+ return seconds + getRepoOrOrg(6,isZh);
+ }else{
+ if(hours > 0){
+ return hours + getRepoOrOrg(4,isZh);
+ }else{
+ return minutes + getRepoOrOrg(5,isZh);
+ }
+ }
+}
+
+function getPRLink(record){
+ return "/" + record.Repo.OwnerName + "/" + record.Repo.Name + "/pulls/" + getIssueId(record);
+}
+function getPRText(record){
+ return record.Repo.OwnerName + "/" + record.Repo.Name + "#" + getIssueId(record);
+}
+
+function getIssueLink(record){
+
+ return "/" + record.Repo.OwnerName + "/" + record.Repo.Name + "/issues/" + getIssueId(record);
+}
+
+function getIssueId(record){
+ var Id = "1";
+ if(!isEmpty(record.Comment) && !isEmpty(record.Comment.Issue)){
+ Id = record.Comment.Issue.Index;
+ }else{
+ if(!isEmpty(record.Content)){
+ var content = record.Content;
+ var index = content.indexOf("|");
+ if(index != -1){
+ Id = content.substring(0,index);
+ }
+ }
+ }
+ return Id;
+}
+
+function getIssueText(record){
+ return record.Repo.OwnerName + "/" + record.Repo.Name + "#" + getIssueId(record);
+}
+
+/*
+ ActionCreateRepo ActionType = iota + 1 // 1
+ ActionRenameRepo // 2
+ ActionStarRepo // 3
+ ActionWatchRepo // 4
+ ActionCommitRepo // 5
+ ActionCreateIssue // 6
+ ActionCreatePullRequest // 7
+ ActionTransferRepo // 8
+ ActionPushTag // 9
+ ActionCommentIssue // 10
+ ActionMergePullRequest // 11
+ ActionCloseIssue // 12
+ ActionReopenIssue // 13
+ ActionClosePullRequest // 14
+ ActionReopenPullRequest // 15
+ ActionDeleteTag // 16
+ ActionDeleteBranch // 17
+ ActionMirrorSyncPush // 18
+ ActionMirrorSyncCreate // 19
+ ActionMirrorSyncDelete // 20
+ ActionApprovePullRequest // 21
+ ActionRejectPullRequest // 22
+ ActionCommentPull // 23
+*/
+
+var actionNameZH={
+ "1":"创建了项目",
+ "2":"重命名项目 {oldRepoName} 为",
+ "5":"推送了 {branch} 分支的代码到",
+ "6":"创建了任务",
+ "7":"创建了合并请求",
+ "9":"推送了 {branch} 分支的代码到",
+ "10":"评论了任务",
+ "11":"合并了合并请求",
+ "12":"关闭了任务",
+ "13":"重新开启了任务",
+ "14":"关闭了合并请求",
+ "15":"重新开启了合并请求",
+ "17":"从 {repoName} 删除分支 {deleteBranchName}",
+ "22":"拒绝了合并请求",
+ "23":"评论了合并请求"
+};
+
+var actionNameEN={
+ "1":" created repository",
+ "2":" renamed repository from {oldRepoName} to ",
+ "5":" pushed to {branch} at",
+ "6":" opened issue",
+ "7":" created pull request",
+ "9":" pushed to {branch} at",
+ "10":" commented on issue",
+ "11":" merged pull request",
+ "12":" closed issue",
+ "13":" reopened issue",
+ "14":" closed pull request",
+ "15":" reopened pull request",
+ "17":" deleted branch {deleteBranchName} from {repoName}",
+ "22":" rejected pull request",
+ "23":" commented on pull request"
+};
+
+var repoAndOrgZH={
+ "1":"项目",
+ "2":"成员",
+ "3":"团队",
+ "4":"小时前",
+ "5":"分钟前",
+ "6":"秒前"
+};
+
+var repoAndOrgEN={
+ "1":"repository",
+ "2":"Members ",
+ "3":"Teams",
+ "4":" hours ago",
+ "5":" minutes ago",
+ "6":" seconds ago"
+};
+
+
+function getAction(opType,isZh){
+ if(isZh){
+ return actionNameZH[opType]
+ }else{
+ return actionNameEN[opType]
+ }
+}
+
+queryRecommendData();
+
+function queryRecommendData(){
+ $.ajax({
+ type:"GET",
+ url:"/recommend/org",
+ headers: {
+ authorization:token,
+ },
+ dataType:"json",
+ async:false,
+ success:function(json){
+ console.log(json);
+ displayOrg(json);
+ },
+ error:function(response) {
+ console.log(response);
+ }
+ });
+
+ $.ajax({
+ type:"GET",
+ url:"/recommend/repo",
+ headers: {
+ authorization:token,
+ },
+ dataType:"json",
+ async:false,
+ success:function(json){
+ console.log(json);
+ displayRepo(json);
+ },
+ error:function(response) {
+ console.log(response);
+ }
+ });
+
+}
+
+/*
+
+
+
+
+ 276 32
+
+

+
+
+
+ 本项目是群体化方法与技术的开源实现案例,在基于Gitea的基础上,进一步支持社交化的协同开发、协同学习、协同研究等群体创新实践服务,特别是针对新一代人工智能技术特点,重点支持项目管理、git代码管理、大数据集存储管理与智能计算平台接入。
+
+
+
+
+
+*/
+function displayRepo(json){
+ var orgRepo = document.getElementById("recommendrepo");
+ var html = "";
+ if (json != null && json.length > 0){
+ for(var i = 0; i < json.length;i++){
+ var record = json[i]
+ html += "
";
+ html += "
";
+ html += "
";
+ html += "
";
+ html += " " + record["NumStars"] + "" + record["NumForks"];
+ html += " ";
+ html += "

";
+ html += " ";
+ html += "
" + record["Description"] + "
";
+ html += "
"
+ if(record["Topics"] != null){
+ for(var j = 0; j < record["Topics"].length; j++){
+ topic = record["Topics"][j];
+ url = "/explore/repos?q=" + (topic) + "&topic="
+ html += "
" + topic + "";
+ }
+ }
+ html += "
";
+ html += "
";
+ html += "
";
+ html += "
";
+ }
+ }
+ orgRepo.innerHTML = html;
+ swiperRepo.updateSlides();
+ swiperRepo.updateProgress();
+}
+
+/**
+ *
+ *
+
+ */
+
+//var repoAndOrgZH = new Map([['1', "项目"], ['2', "成员"], ['3', "团队"]]);
+//var repoAndOrgEN = new Map([['1', "Repository"], ['2', "Members"], ['3', "Teams"]]);
+
+
+function getRepoOrOrg(key,isZhLang){
+ if(isZhLang){
+ return repoAndOrgZH[key];
+ }else{
+ return repoAndOrgEN[key];
+ }
+}
+
+function displayOrg(json){
+ var orgDiv = document.getElementById("recommendorg");
+ var html = "";
+ if (json != null && json.length > 0){
+ for(var i = 0; i < json.length;i++){
+ var record = json[i]
+ html += "
";
+ }
+ }
+ orgDiv.innerHTML = html;
+}
\ No newline at end of file
diff --git a/routers/actionnotification.go b/routers/actionnotification.go
index b3e151c1c..31e25a65e 100644
--- a/routers/actionnotification.go
+++ b/routers/actionnotification.go
@@ -1,6 +1,8 @@
package routers
import (
+ "net/http"
+
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/log"
@@ -11,6 +13,9 @@ import (
var upgrader = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
+ CheckOrigin: func(r *http.Request) bool {
+ return true
+ },
}
var SocketManager = socketwrap.NewClientsManager()
@@ -24,7 +29,7 @@ func ActionNotification(ctx *context.Context) {
}
client := &socketwrap.Client{Manager: SocketManager, Conn: conn, Send: make(chan *models.Action, 256)}
- WriteLastTenActionsIfHave(conn)
+ WriteLastActionsIfHave(conn)
client.Manager.Register <- client
@@ -32,22 +37,20 @@ func ActionNotification(ctx *context.Context) {
}
-func WriteLastTenActionsIfHave(conn *websocket.Conn) {
- socketwrap.LastTenActionsQueue.Mutex.RLock()
+func WriteLastActionsIfHave(conn *websocket.Conn) {
+ socketwrap.LastActionsQueue.Mutex.RLock()
{
- size := socketwrap.LastTenActionsQueue.Queue.Len()
+ size := socketwrap.LastActionsQueue.Queue.Len()
if size > 0 {
- tempE := socketwrap.LastTenActionsQueue.Queue.Front()
- conn.WriteJSON(tempE)
+ tempE := socketwrap.LastActionsQueue.Queue.Front()
+ conn.WriteJSON(tempE.Value)
for i := 1; i < size; i++ {
tempE = tempE.Next()
- conn.WriteJSON(tempE)
+ conn.WriteJSON(tempE.Value)
}
}
}
- socketwrap.LastTenActionsQueue.Mutex.RUnlock()
+ socketwrap.LastActionsQueue.Mutex.RUnlock()
}
-
-
diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go
index 518c63e4f..dcea46ed6 100755
--- a/routers/api/v1/api.go
+++ b/routers/api/v1/api.go
@@ -524,7 +524,7 @@ func RegisterRoutes(m *macaron.Macaron) {
Get(notify.GetThread).
Patch(notify.ReadThread)
}, reqToken())
-
+
operationReq := context.Toggle(&context.ToggleOptions{SignInRequired: true, OperationRequired: true})
//Project board
m.Group("/projectboard", func() {
@@ -544,7 +544,13 @@ func RegisterRoutes(m *macaron.Macaron) {
}, operationReq)
m.Get("/query_user_static_page", operationReq, repo_ext.QueryUserStaticDataPage)
-
+ m.Get("/query_user_current_month", operationReq, repo_ext.QueryUserStaticCurrentMonth)
+ m.Get("/query_user_current_week", operationReq, repo_ext.QueryUserStaticCurrentWeek)
+ m.Get("/query_user_current_year", operationReq, repo_ext.QueryUserStaticCurrentYear)
+ m.Get("/query_user_last30_day", operationReq, repo_ext.QueryUserStaticLast30Day)
+ m.Get("/query_user_last_month", operationReq, repo_ext.QueryUserStaticLastMonth)
+ m.Get("/query_user_yesterday", operationReq, repo_ext.QueryUserStaticYesterday)
+ m.Get("/query_user_all", operationReq, repo_ext.QueryUserStaticAll)
// Users
m.Group("/users", func() {
m.Get("/search", user.Search)
diff --git a/routers/api/v1/repo/modelarts.go b/routers/api/v1/repo/modelarts.go
index 283696007..05c31b5f5 100755
--- a/routers/api/v1/repo/modelarts.go
+++ b/routers/api/v1/repo/modelarts.go
@@ -6,6 +6,7 @@
package repo
import (
+ "code.gitea.io/gitea/modules/util"
"net/http"
"strconv"
"strings"
@@ -106,7 +107,7 @@ func GetModelArtsTrainJobVersion(ctx *context.APIContext) {
job.TrainJobDuration = result.TrainJobDuration
if result.Duration != 0 {
- job.TrainJobDuration = addZero(result.Duration/3600000) + ":" + addZero(result.Duration%3600000/60000) + ":" + addZero(result.Duration%60000/1000)
+ job.TrainJobDuration = util.AddZero(result.Duration/3600000) + ":" + util.AddZero(result.Duration%3600000/60000) + ":" + util.AddZero(result.Duration%60000/1000)
} else {
job.TrainJobDuration = "00:00:00"
@@ -125,15 +126,6 @@ func GetModelArtsTrainJobVersion(ctx *context.APIContext) {
}
-func addZero(t int64) (m string) {
- if t < 10 {
- m = "0" + strconv.FormatInt(t, 10)
- return m
- } else {
- return strconv.FormatInt(t, 10)
- }
-}
-
func TrainJobGetLog(ctx *context.APIContext) {
var (
err error
diff --git a/routers/home.go b/routers/home.go
index 7cc353ed8..24de1a10c 100755
--- a/routers/home.go
+++ b/routers/home.go
@@ -44,9 +44,52 @@ const (
func Home(ctx *context.Context) {
ctx.Data["PageIsHome"] = true
ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
+ setRecommendURL(ctx)
ctx.HTML(200, tplHome)
}
+func setRecommendURL(ctx *context.Context) {
+ addr := setting.RecommentRepoAddr[10:]
+ start := strings.Index(addr, "/")
+ end := strings.Index(addr, "raw")
+ if start != -1 && end != -1 {
+ ctx.Data["RecommendURL"] = addr[start:end]
+ } else {
+ ctx.Data["RecommendURL"] = setting.RecommentRepoAddr
+ }
+
+ ctx.Data["page_title"] = ctx.Tr("home.page_title")
+ ctx.Data["page_small_title"] = ctx.Tr("home.page_small_title")
+ ctx.Data["page_description"] = ctx.Tr("home.page_description")
+ ctx.Data["page_use"] = ctx.Tr("home.page_use")
+ ctx.Data["page_only_dynamic"] = ctx.Tr("home.page_only_dynamic")
+ ctx.Data["page_recommend_org"] = ctx.Tr("home.page_recommend_org")
+ ctx.Data["page_recommend_org_desc"] = ctx.Tr("home.page_recommend_org_desc")
+ ctx.Data["page_recommend_org_commit"] = ctx.Tr("home.page_recommend_org_commit")
+ ctx.Data["page_recommend_org_more"] = ctx.Tr("home.page_recommend_org_more")
+ ctx.Data["page_recommend_repo"] = ctx.Tr("home.page_recommend_repo")
+ ctx.Data["page_recommend_repo_desc"] = ctx.Tr("home.page_recommend_repo_desc")
+ ctx.Data["page_recommend_repo_commit"] = ctx.Tr("home.page_recommend_repo_commit")
+ ctx.Data["page_recommend_repo_go"] = ctx.Tr("home.page_recommend_repo_go")
+ ctx.Data["page_recommend_repo_more"] = ctx.Tr("home.page_recommend_repo_more")
+ ctx.Data["page_dev_env"] = ctx.Tr("home.page_dev_env")
+ ctx.Data["page_dev_env_desc"] = ctx.Tr("home.page_dev_env_desc")
+ ctx.Data["page_dev_env_desc_title"] = ctx.Tr("home.page_dev_env_desc_title")
+ ctx.Data["page_dev_env_desc_desc"] = ctx.Tr("home.page_dev_env_desc_desc")
+ ctx.Data["page_dev_env_desc1_title"] = ctx.Tr("home.page_dev_env_desc1_title")
+ ctx.Data["page_dev_env_desc1_desc"] = ctx.Tr("home.page_dev_env_desc1_desc")
+ ctx.Data["page_dev_env_desc2_title"] = ctx.Tr("home.page_dev_env_desc2_title")
+ ctx.Data["page_dev_env_desc2_desc"] = ctx.Tr("home.page_dev_env_desc2_desc")
+ ctx.Data["page_dev_env_desc3_title"] = ctx.Tr("home.page_dev_env_desc3_title")
+ ctx.Data["page_dev_env_desc3_desc"] = ctx.Tr("home.page_dev_env_desc3_desc")
+ ctx.Data["page_dev_yunlao"] = ctx.Tr("home.page_dev_yunlao")
+ ctx.Data["page_dev_yunlao_desc1"] = ctx.Tr("home.page_dev_yunlao_desc1")
+ ctx.Data["page_dev_yunlao_desc2"] = ctx.Tr("home.page_dev_yunlao_desc2")
+ ctx.Data["page_dev_yunlao_desc3"] = ctx.Tr("home.page_dev_yunlao_desc3")
+ ctx.Data["page_dev_yunlao_desc4"] = ctx.Tr("home.page_dev_yunlao_desc4")
+ ctx.Data["page_dev_yunlao_apply"] = ctx.Tr("home.page_dev_yunlao_apply")
+}
+
func Dashboard(ctx *context.Context) {
if ctx.IsSigned {
if !ctx.User.IsActive && setting.Service.RegisterEmailConfirm {
@@ -77,7 +120,7 @@ func Dashboard(ctx *context.Context) {
ctx.Redirect(setting.AppSubURL + "/user/login")
return
}
-
+ setRecommendURL(ctx)
ctx.Data["PageIsHome"] = true
ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
ctx.HTML(200, tplHome)
@@ -513,43 +556,92 @@ func NotFound(ctx *context.Context) {
ctx.Data["Title"] = "Page Not Found"
ctx.NotFound("home.NotFound", nil)
}
+
func RecommendOrgFromPromote(ctx *context.Context) {
url := setting.RecommentRepoAddr + "organizations"
- recommendFromPromote(ctx, url)
+ result, err := recommendFromPromote(url)
+ if err != nil {
+ ctx.ServerError("500", err)
+ return
+ }
+ resultOrg := make([]map[string]interface{}, 0)
+ for _, userName := range result {
+ user, err := models.GetUserByName(userName)
+ if err == nil {
+ userMap := make(map[string]interface{})
+ userMap["Name"] = user.Name
+ userMap["Description"] = user.Description
+ userMap["FullName"] = user.FullName
+ userMap["ID"] = user.ID
+ userMap["Avatar"] = user.RelAvatarLink()
+ userMap["NumRepos"] = user.NumRepos
+ userMap["NumTeams"] = user.NumTeams
+ userMap["NumMembers"] = user.NumMembers
+ resultOrg = append(resultOrg, userMap)
+ } else {
+ log.Info("query user error," + err.Error())
+ }
+ }
+
+ ctx.JSON(200, resultOrg)
}
-func recommendFromPromote(ctx *context.Context, url string) {
+func recommendFromPromote(url string) ([]string, error) {
resp, err := http.Get(url)
- if err != nil {
+ if err != nil || resp.StatusCode != 200 {
log.Info("Get organizations url error=" + err.Error())
- ctx.ServerError("QueryTrainJobList:", err)
- return
+ return nil, err
}
bytes, err := ioutil.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
log.Info("Get organizations url error=" + err.Error())
- ctx.ServerError("QueryTrainJobList:", err)
- return
+ return nil, err
}
allLineStr := string(bytes)
lines := strings.Split(allLineStr, "\n")
result := make([]string, len(lines))
for i, line := range lines {
-
- tmpIndex := strings.Index(line, ".")
- log.Info("i=" + fmt.Sprint(i) + " line=" + line + " tmpIndex=" + fmt.Sprint(tmpIndex))
- if tmpIndex == -1 {
- result[i] = strings.Trim(line, " ")
- } else {
- result[i] = strings.Trim(line[tmpIndex+1:], " ")
- }
+ log.Info("i=" + fmt.Sprint(i) + " line=" + line)
+ result[i] = strings.Trim(line, " ")
}
- ctx.JSON(http.StatusOK, result)
+ return result, nil
}
func RecommendRepoFromPromote(ctx *context.Context) {
url := setting.RecommentRepoAddr + "projects"
- recommendFromPromote(ctx, url)
+ result, err := recommendFromPromote(url)
+ if err != nil {
+ ctx.ServerError("500", err)
+ return
+ }
+ resultRepo := make([]map[string]interface{}, 0)
+ //resultRepo := make([]*models.Repository, 0)
+ for _, repoName := range result {
+ tmpIndex := strings.Index(repoName, "/")
+ if tmpIndex == -1 {
+ log.Info("error repo name format.")
+ } else {
+ ownerName := strings.Trim(repoName[0:tmpIndex], " ")
+ repoName := strings.Trim(repoName[tmpIndex+1:], " ")
+ repo, err := models.GetRepositoryByOwnerAndName(ownerName, repoName)
+ if err == nil {
+ repoMap := make(map[string]interface{})
+ repoMap["ID"] = fmt.Sprint(repo.ID)
+ repoMap["Name"] = repo.Name
+ repoMap["OwnerName"] = repo.OwnerName
+ repoMap["NumStars"] = repo.NumStars
+ repoMap["NumForks"] = repo.NumForks
+ repoMap["Description"] = repo.Description
+ repoMap["NumWatchs"] = repo.NumWatches
+ repoMap["Topics"] = repo.Topics
+ repoMap["Avatar"] = repo.RelAvatarLink()
+ resultRepo = append(resultRepo, repoMap)
+ } else {
+ log.Info("query repo error," + err.Error())
+ }
+ }
+ }
+ ctx.JSON(200, resultRepo)
}
diff --git a/routers/notice/notice.go b/routers/notice/notice.go
new file mode 100644
index 000000000..f1e996e2d
--- /dev/null
+++ b/routers/notice/notice.go
@@ -0,0 +1,87 @@
+package notice
+
+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"
+ "time"
+)
+
+var noticeCache = cache.New(2*time.Minute, 1*time.Minute)
+
+const (
+ NOTICE_CACHE_KEY = "notice"
+)
+
+type Notice struct {
+ Title string
+ Link string
+ Visible int //0 invisible, 1 visible
+ CommitId string
+}
+
+var lock int32 = 0
+
+func GetNewestNotice() (*Notice, error) {
+ defer func() {
+ if err := recover(); err != nil {
+ log.Error("recover error", err)
+ }
+ }()
+
+ var notice *Notice
+ var err error
+ if setting.CacheOn {
+ notice, err = getNewestNoticeFromCacheAndDisk()
+ } else {
+ notice, err = getNewestNoticeFromDisk()
+ }
+
+ if err != nil {
+ return nil, err
+ }
+ return notice, nil
+}
+
+func getNoticeTimeout() time.Duration {
+ return time.Duration(setting.CacheTimeOutSecond) * time.Second
+}
+
+func getNewestNoticeFromDisk() (*Notice, error) {
+ log.Debug("Get notice from disk")
+ repoFile, err := models.ReadLatestFileInRepo(setting.UserNameOfNoticeRepo, setting.RepoNameOfNoticeRepo, setting.RefNameOfNoticeRepo, setting.TreePathOfNoticeRepo)
+ if err != nil {
+ log.Error("GetNewestNotice failed, error=%v", err)
+ return nil, err
+ }
+ notice := &Notice{}
+ json.Unmarshal(repoFile.Content, notice)
+ if notice.Title == "" {
+ return nil, err
+ }
+ notice.CommitId = repoFile.CommitId
+ return notice, nil
+}
+
+func getNewestNoticeFromCacheAndDisk() (*Notice, error) {
+ v, success := noticeCache.Get(NOTICE_CACHE_KEY)
+ if success {
+ log.Debug("Get notice from cache,value = %v", v)
+ if v == nil {
+ return nil, nil
+ }
+ n := v.(*Notice)
+ return n, nil
+ }
+
+ notice, err := getNewestNoticeFromDisk()
+ if err != nil {
+ log.Error("GetNewestNotice failed, error=%v", err)
+ noticeCache.Set(NOTICE_CACHE_KEY, nil, 30*time.Second)
+ return nil, err
+ }
+ noticeCache.Set(NOTICE_CACHE_KEY, notice, getNoticeTimeout())
+ return notice, nil
+}
diff --git a/routers/repo/ai_model_manage.go b/routers/repo/ai_model_manage.go
index 669bdf9fa..845dbbc6b 100644
--- a/routers/repo/ai_model_manage.go
+++ b/routers/repo/ai_model_manage.go
@@ -99,6 +99,18 @@ func saveModelByParameters(jobId string, versionName string, name string, versio
//udpate status and version count
models.ModifyModelNewProperty(lastNewModelId, MODEL_NOT_LATEST, 0)
}
+ var units []models.RepoUnit
+ var deleteUnitTypes []models.UnitType
+ units = append(units, models.RepoUnit{
+ RepoID: ctx.Repo.Repository.ID,
+ Type: models.UnitTypeModelManage,
+ Config: &models.ModelManageConfig{
+ EnableModelManage: true,
+ },
+ })
+ deleteUnitTypes = append(deleteUnitTypes, models.UnitTypeModelManage)
+
+ models.UpdateRepositoryUnits(ctx.Repo.Repository, units, deleteUnitTypes)
log.Info("save model end.")
@@ -130,10 +142,13 @@ func SaveModel(ctx *context.Context) {
version := ctx.Query("Version")
label := ctx.Query("Label")
description := ctx.Query("Description")
+ trainTaskCreate := ctx.QueryBool("trainTaskCreate")
- if !ctx.Repo.CanWrite(models.UnitTypeModelManage) {
- ctx.ServerError("No right.", errors.New(ctx.Tr("repo.model_noright")))
- return
+ if !trainTaskCreate {
+ if !ctx.Repo.CanWrite(models.UnitTypeModelManage) {
+ ctx.ServerError("No right.", errors.New(ctx.Tr("repo.model_noright")))
+ return
+ }
}
if JobId == "" || VersionName == "" {
@@ -474,6 +489,23 @@ func ShowOneVersionOtherModel(ctx *context.Context) {
func ShowModelTemplate(ctx *context.Context) {
ctx.Data["isModelManage"] = true
+ repoId := ctx.Repo.Repository.ID
+ Type := -1
+ _, count, _ := models.QueryModel(&models.AiModelQueryOptions{
+ ListOptions: models.ListOptions{
+ Page: 1,
+ PageSize: 2,
+ },
+ RepoID: repoId,
+ Type: Type,
+ New: MODEL_LATEST,
+ })
+ ctx.Data["MODEL_COUNT"] = count
+
+ _, trainCount, _ := models.QueryModelTrainJobList(repoId)
+ log.Info("query train count=" + fmt.Sprint(trainCount))
+
+ ctx.Data["TRAIN_COUNT"] = trainCount
ctx.HTML(200, tplModelManageIndex)
}
@@ -586,3 +618,67 @@ func ModifyModelInfo(ctx *context.Context) {
}
}
+
+func QueryModelListForPredict(ctx *context.Context) {
+ repoId := ctx.Repo.Repository.ID
+ modelResult, count, err := models.QueryModel(&models.AiModelQueryOptions{
+ ListOptions: models.ListOptions{
+ Page: -1,
+ PageSize: -1,
+ },
+ RepoID: repoId,
+ Type: -1,
+ New: -1,
+ })
+ if err != nil {
+ ctx.ServerError("Cloudbrain", err)
+ return
+ }
+ log.Info("query return count=" + fmt.Sprint(count))
+
+ nameList := make([]string, 0)
+
+ nameMap := make(map[string][]*models.AiModelManage)
+ for _, model := range modelResult {
+ if _, value := nameMap[model.Name]; !value {
+ models := make([]*models.AiModelManage, 0)
+ models = append(models, model)
+ nameMap[model.Name] = models
+ nameList = append(nameList, model.Name)
+ } else {
+ nameMap[model.Name] = append(nameMap[model.Name], model)
+ }
+ }
+
+ mapInterface := make(map[string]interface{})
+ mapInterface["nameList"] = nameList
+ mapInterface["nameMap"] = nameMap
+ ctx.JSON(http.StatusOK, mapInterface)
+}
+
+func QueryModelFileForPredict(ctx *context.Context) {
+ id := ctx.Query("ID")
+ model, err := models.QueryModelById(id)
+ if err != nil {
+ log.Error("no such model!", err.Error())
+ ctx.ServerError("no such model:", err)
+ return
+ }
+ prefix := model.Path[len(setting.Bucket)+1:]
+ fileinfos, err := storage.GetAllObjectByBucketAndPrefix(setting.Bucket, prefix)
+ ctx.JSON(http.StatusOK, fileinfos)
+}
+
+func QueryOneLevelModelFile(ctx *context.Context) {
+ id := ctx.Query("ID")
+ parentDir := ctx.Query("parentDir")
+ model, err := models.QueryModelById(id)
+ if err != nil {
+ log.Error("no such model!", err.Error())
+ ctx.ServerError("no such model:", err)
+ return
+ }
+ prefix := model.Path[len(setting.Bucket)+1:]
+ fileinfos, err := storage.GetOneLevelAllObjectUnderDir(setting.Bucket, prefix, parentDir)
+ ctx.JSON(http.StatusOK, fileinfos)
+}
diff --git a/routers/repo/blame.go b/routers/repo/blame.go
index 00ef9a99e..6ab357c09 100644
--- a/routers/repo/blame.go
+++ b/routers/repo/blame.go
@@ -6,13 +6,6 @@ package repo
import (
"bytes"
- "container/list"
- "fmt"
- "html"
- gotemplate "html/template"
- "net/url"
- "strings"
-
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/context"
@@ -22,6 +15,12 @@ import (
"code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/timeutil"
+ "container/list"
+ "fmt"
+ "html"
+ gotemplate "html/template"
+ "net/url"
+ "strings"
)
const (
@@ -35,7 +34,52 @@ func RefBlame(ctx *context.Context) {
ctx.NotFound("Blame FileName", nil)
return
}
-
+ //get repo contributors info
+ contributors, err := git.GetContributors(ctx.Repo.Repository.RepoPath(), ctx.Repo.BranchName)
+ if err == nil && contributors != nil {
+ var contributorInfos []*ContributorInfo
+ contributorInfoHash := make(map[string]*ContributorInfo)
+ count := 0
+ for _, c := range contributors {
+ if count >= 25 {
+ continue
+ }
+ if strings.Compare(c.Email, "") == 0 {
+ continue
+ }
+ // get user info from committer email
+ user, err := models.GetUserByActivateEmail(c.Email)
+ if err == nil {
+ // committer is system user, get info through user's primary email
+ if existedContributorInfo, ok := contributorInfoHash[user.Email]; ok {
+ // existed: same primary email, different committer name
+ existedContributorInfo.CommitCnt += c.CommitCnt
+ } else {
+ // new committer info
+ var newContributor = &ContributorInfo{
+ user, user.RelAvatarLink(), user.Name, user.Email, c.CommitCnt,
+ }
+ count++
+ contributorInfos = append(contributorInfos, newContributor)
+ contributorInfoHash[user.Email] = newContributor
+ }
+ } else {
+ // committer is not system user
+ if existedContributorInfo, ok := contributorInfoHash[c.Email]; ok {
+ // existed: same primary email, different committer name
+ existedContributorInfo.CommitCnt += c.CommitCnt
+ } else {
+ var newContributor = &ContributorInfo{
+ user, "", "", c.Email, c.CommitCnt,
+ }
+ count++
+ contributorInfos = append(contributorInfos, newContributor)
+ contributorInfoHash[c.Email] = newContributor
+ }
+ }
+ }
+ ctx.Data["ContributorInfo"] = contributorInfos
+ }
userName := ctx.Repo.Owner.Name
repoName := ctx.Repo.Repository.Name
commitID := ctx.Repo.CommitID
diff --git a/routers/repo/cloudbrain.go b/routers/repo/cloudbrain.go
index ab3303408..ca1d08101 100755
--- a/routers/repo/cloudbrain.go
+++ b/routers/repo/cloudbrain.go
@@ -14,18 +14,17 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/modules/modelarts"
-
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/storage"
-
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/auth"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/cloudbrain"
"code.gitea.io/gitea/modules/context"
+ "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/modelarts"
"code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/storage"
+ "code.gitea.io/gitea/modules/util"
)
const (
@@ -220,7 +219,7 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) {
gpuType = gpuInfo.Value
}
}
- downloadRateCode(repo, jobName, setting.BenchmarkOwner, setting.BrainScoreName, benchmarkPath, form.BenchmarkCategory, gpuType)
+ downloadRateCode(repo, jobName, setting.BenchmarkOwner, setting.BenchmarkName, benchmarkPath, form.BenchmarkCategory, gpuType)
uploadCodeToMinio(benchmarkPath+"/", jobName, cloudbrain.BenchMarkMountPath+"/")
}
@@ -252,17 +251,10 @@ func CloudBrainRestart(ctx *context.Context) {
var jobID = ctx.Params(":jobid")
var resultCode = "0"
var errorMsg = ""
- var status = ""
+ var status = string(models.JobWaiting)
+ task := ctx.Cloudbrain
for {
- task, err := models.GetCloudbrainByJobID(jobID)
- if err != nil {
- log.Error("GetCloudbrainByJobID(%s) failed:%v", jobID, err.Error(), ctx.Data["MsgID"])
- resultCode = "-1"
- errorMsg = "system error"
- break
- }
-
if task.Status != string(models.JobStopped) && task.Status != string(models.JobSucceeded) && task.Status != string(models.JobFailed) {
log.Error("the job(%s) is not stopped", task.JobName, ctx.Data["MsgID"])
resultCode = "-1"
@@ -277,7 +269,7 @@ func CloudBrainRestart(ctx *context.Context) {
break
}
- if !ctx.IsSigned || (ctx.User.ID != task.UserID && !ctx.IsUserSiteAdmin()){
+ if !ctx.IsSigned || (ctx.User.ID != task.UserID && !ctx.IsUserSiteAdmin()) {
log.Error("the user has no right ro restart the job", task.JobName, ctx.Data["MsgID"])
resultCode = "-1"
errorMsg = "you have no right to restart the job"
@@ -299,7 +291,7 @@ func CloudBrainRestart(ctx *context.Context) {
}
}
- err = cloudbrain.RestartTask(ctx, task)
+ err = cloudbrain.RestartTask(ctx, task, &jobID)
if err != nil {
log.Error("RestartTask failed:%v", err.Error(), ctx.Data["MsgID"])
resultCode = "-1"
@@ -307,9 +299,6 @@ func CloudBrainRestart(ctx *context.Context) {
break
}
- status = task.Status
- jobID = task.JobID
-
break
}
@@ -370,46 +359,19 @@ func CloudBrainShow(ctx *context.Context) {
}
func CloudBrainDebug(ctx *context.Context) {
- var jobID = ctx.Params(":jobid")
- if !ctx.IsSigned {
- log.Error("the user has not signed in")
- ctx.Error(http.StatusForbidden, "", "the user has not signed in")
- return
- }
- task, err := models.GetCloudbrainByJobID(jobID)
- if err != nil {
- ctx.ServerError("GetCloudbrainByJobID failed", err)
- return
- }
-
- debugUrl := setting.DebugServerHost + "jpylab_" + task.JobID + "_" + task.SubTaskName
+ debugUrl := setting.DebugServerHost + "jpylab_" + ctx.Cloudbrain.JobID + "_" + ctx.Cloudbrain.SubTaskName
ctx.Redirect(debugUrl)
}
func CloudBrainCommitImage(ctx *context.Context, form auth.CommitImageCloudBrainForm) {
- var jobID = ctx.Params(":jobid")
- if !ctx.IsSigned {
- log.Error("the user has not signed in")
- ctx.Error(http.StatusForbidden, "", "the user has not signed in")
- return
- }
- task, err := models.GetCloudbrainByJobID(jobID)
- if err != nil {
- ctx.JSON(200, map[string]string{
- "result_code": "-1",
- "error_msg": "GetCloudbrainByJobID failed",
- })
- return
- }
-
- err = cloudbrain.CommitImage(jobID, models.CommitImageParams{
- Ip: task.ContainerIp,
- TaskContainerId: task.ContainerID,
+ err := cloudbrain.CommitImage(ctx.Cloudbrain.JobID, models.CommitImageParams{
+ Ip: ctx.Cloudbrain.ContainerIp,
+ TaskContainerId: ctx.Cloudbrain.ContainerID,
ImageDescription: form.Description,
ImageTag: form.Tag,
})
if err != nil {
- log.Error("CommitImage(%s) failed:%v", task.JobName, err.Error(), ctx.Data["msgID"])
+ log.Error("CommitImage(%s) failed:%v", ctx.Cloudbrain.JobName, err.Error(), ctx.Data["msgID"])
ctx.JSON(200, map[string]string{
"result_code": "-1",
"error_msg": "CommitImage failed",
@@ -429,15 +391,8 @@ func CloudBrainStop(ctx *context.Context) {
var errorMsg = ""
var status = ""
+ task := ctx.Cloudbrain
for {
- task, err := models.GetCloudbrainByJobID(jobID)
- if err != nil {
- log.Error("GetCloudbrainByJobID(%s) failed:%v", task.JobName, err, ctx.Data["msgID"])
- resultCode = "-1"
- errorMsg = "system error"
- break
- }
-
if task.Status == string(models.JobStopped) || task.Status == string(models.JobFailed) {
log.Error("the job(%s) has been stopped", task.JobName, ctx.Data["msgID"])
resultCode = "-1"
@@ -445,7 +400,7 @@ func CloudBrainStop(ctx *context.Context) {
break
}
- err = cloudbrain.StopJob(jobID)
+ err := cloudbrain.StopJob(jobID)
if err != nil {
log.Error("StopJob(%s) failed:%v", task.JobName, err, ctx.Data["msgID"])
resultCode = "-1"
@@ -555,12 +510,7 @@ func logErrorAndUpdateJobStatus(err error, taskInfo *models.Cloudbrain) {
}
func CloudBrainDel(ctx *context.Context) {
- var jobID = ctx.Params(":jobid")
- task, err := models.GetCloudbrainByJobID(jobID)
- if err != nil {
- ctx.ServerError("GetCloudbrainByJobID failed", err)
- return
- }
+ task := ctx.Cloudbrain
if task.Status != string(models.JobStopped) && task.Status != string(models.JobFailed) {
log.Error("the job(%s) has not been stopped", task.JobName, ctx.Data["msgID"])
@@ -568,7 +518,7 @@ func CloudBrainDel(ctx *context.Context) {
return
}
- err = models.DeleteJob(task)
+ err := models.DeleteJob(task)
if err != nil {
ctx.ServerError("DeleteJob failed", err)
return
@@ -949,6 +899,13 @@ func SyncCloudbrainStatus() {
task.Duration = result.Duration
task.TrainJobDuration = result.TrainJobDuration
+ if result.Duration != 0 {
+ task.TrainJobDuration = util.AddZero(result.Duration/3600000) + ":" + util.AddZero(result.Duration%3600000/60000) + ":" + util.AddZero(result.Duration%60000/1000)
+
+ } else {
+ task.TrainJobDuration = "00:00:00"
+ }
+
err = models.UpdateJob(task)
if err != nil {
log.Error("UpdateJob(%s) failed:%v", task.JobName, err)
diff --git a/routers/repo/issue.go b/routers/repo/issue.go
index 7ab5eb283..42a6b9609 100755
--- a/routers/repo/issue.go
+++ b/routers/repo/issue.go
@@ -13,6 +13,7 @@ import (
"net/http"
"strconv"
"strings"
+ "time"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/auth"
@@ -336,6 +337,7 @@ func issues(ctx *context.Context, milestoneID int64, isPullOption util.OptionalB
// Issues render issues page
func Issues(ctx *context.Context) {
+ startTime := time.Now()
isPullList := ctx.Params(":type") == "pulls"
if isPullList {
MustAllowPulls(ctx)
@@ -366,6 +368,9 @@ func Issues(ctx *context.Context) {
ctx.Data["CanWriteIssuesOrPulls"] = ctx.Repo.CanWriteIssuesOrPulls(isPullList)
+ duration := time.Since(startTime)
+ log.Info("Issues cost: %v seconds", duration.Seconds())
+
ctx.HTML(200, tplIssues)
}
diff --git a/routers/repo/modelarts.go b/routers/repo/modelarts.go
index a907aca01..7a952394e 100755
--- a/routers/repo/modelarts.go
+++ b/routers/repo/modelarts.go
@@ -140,6 +140,20 @@ func NotebookCreate(ctx *context.Context, form auth.CreateModelArtsNotebookForm)
return
}
}
+ _, err = models.GetCloudbrainByName(jobName)
+ if err == nil {
+ log.Error("the job name did already exist", ctx.Data["MsgID"])
+ cloudBrainNewDataPrepare(ctx)
+ ctx.RenderWithErr("the job name did already exist", tplModelArtsNotebookNew, &form)
+ return
+ } else {
+ if !models.IsErrJobNotExist(err) {
+ log.Error("system error, %v", err, ctx.Data["MsgID"])
+ cloudBrainNewDataPrepare(ctx)
+ ctx.RenderWithErr("system error", tplModelArtsNotebookNew, &form)
+ return
+ }
+ }
err = modelarts.GenerateTask(ctx, jobName, uuid, description, flavor)
if err != nil {
@@ -192,11 +206,6 @@ func NotebookShow(ctx *context.Context) {
func NotebookDebug(ctx *context.Context) {
var jobID = ctx.Params(":jobid")
- _, err := models.GetCloudbrainByJobID(jobID)
- if err != nil {
- ctx.ServerError("GetCloudbrainByJobID failed", err)
- return
- }
result, err := modelarts.GetJob(jobID)
if err != nil {
@@ -325,11 +334,7 @@ func NotebookManage(ctx *context.Context) {
func NotebookDel(ctx *context.Context) {
var jobID = ctx.Params(":jobid")
- task, err := models.GetCloudbrainByJobID(jobID)
- if err != nil {
- ctx.ServerError("GetCloudbrainByJobID failed", err)
- return
- }
+ task := ctx.Cloudbrain
if task.Status != string(models.ModelArtsCreateFailed) && task.Status != string(models.ModelArtsStartFailed) && task.Status != string(models.ModelArtsStopped) {
log.Error("the job(%s) has not been stopped", task.JobName)
@@ -337,7 +342,7 @@ func NotebookDel(ctx *context.Context) {
return
}
- _, err = modelarts.DelNotebook(jobID)
+ _, err := modelarts.DelNotebook(jobID)
if err != nil {
log.Error("DelJob(%s) failed:%v", task.JobName, err.Error())
ctx.ServerError("DelJob failed", err)
@@ -1251,6 +1256,10 @@ func paramCheckCreateTrainJob(form auth.CreateModelArtsTrainJobForm) error {
log.Error("the WorkServerNumber(%d) must be in (1,25)", form.WorkServerNumber)
return errors.New("计算节点数必须在1-25之间")
}
+ if form.BranchName == "" {
+ log.Error("the branch must not be null!", form.BranchName)
+ return errors.New("代码分支不能为空!")
+ }
return nil
}
@@ -1421,14 +1430,9 @@ func TrainJobDel(ctx *context.Context) {
func TrainJobStop(ctx *context.Context) {
var jobID = ctx.Params(":jobid")
- task, err := models.GetCloudbrainByJobID(jobID)
- if err != nil {
- log.Error("GetCloudbrainByJobID(%s) failed:%v", task.JobName, err.Error())
- ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobIndex, nil)
- return
- }
+ task := ctx.Cloudbrain
- _, err = modelarts.StopTrainJob(jobID, strconv.FormatInt(task.VersionID, 10))
+ _, err := modelarts.StopTrainJob(jobID, strconv.FormatInt(task.VersionID, 10))
if err != nil {
log.Error("StopTrainJob(%s) failed:%v", task.JobName, err.Error())
ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobIndex, nil)
diff --git a/routers/repo/user_data_analysis.go b/routers/repo/user_data_analysis.go
index 42189c57f..7df384cc4 100755
--- a/routers/repo/user_data_analysis.go
+++ b/routers/repo/user_data_analysis.go
@@ -15,6 +15,132 @@ import (
"github.com/360EntSecGroup-Skylar/excelize/v2"
)
+const (
+ PAGE_SIZE = 2000
+)
+
+func queryUserDataPage(ctx *context.Context, tableName string, queryObj interface{}) {
+ page := ctx.QueryInt("page")
+ if page <= 0 {
+ page = 1
+ }
+ pageSize := ctx.QueryInt("pageSize")
+ if pageSize <= 0 {
+ pageSize = setting.UI.IssuePagingNum
+ }
+ userName := ctx.Query("userName")
+ IsReturnFile := ctx.QueryBool("IsReturnFile")
+
+ if IsReturnFile {
+ //writer exec file.
+ xlsx := excelize.NewFile()
+ 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"),
+ "C1": ctx.Tr("user.static.codemergecount"),
+ "D1": ctx.Tr("user.static.commitcount"),
+ "E1": ctx.Tr("user.static.issuecount"),
+ "F1": ctx.Tr("user.static.commentcount"),
+ "G1": ctx.Tr("user.static.focusrepocount"),
+ "H1": ctx.Tr("user.static.starrepocount"),
+ "I1": ctx.Tr("user.static.logincount"),
+ "J1": ctx.Tr("user.static.watchedcount"),
+ "K1": ctx.Tr("user.static.commitcodesize"),
+ "L1": ctx.Tr("user.static.solveissuecount"),
+ "M1": ctx.Tr("user.static.encyclopediascount"),
+ "N1": ctx.Tr("user.static.createrepocount"),
+ "O1": ctx.Tr("user.static.openiindex"),
+ "P1": ctx.Tr("user.static.registdate"),
+ "Q1": ctx.Tr("user.static.countdate"),
+ }
+ for k, v := range dataHeader {
+ //设置单元格的值
+ xlsx.SetCellValue(sheetName, k, v)
+ }
+ _, count := models.QueryUserStaticDataByTableName(1, 1, tableName, queryObj, userName)
+ var indexTotal int64
+ indexTotal = 0
+ for {
+ re, _ := models.QueryUserStaticDataByTableName(int(indexTotal), PAGE_SIZE, tableName, queryObj, "")
+ log.Info("return count=" + fmt.Sprint(count))
+ 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.CommitCount)
+ xlsx.SetCellValue(sheetName, "E"+rows, userRecord.IssueCount)
+ xlsx.SetCellValue(sheetName, "F"+rows, userRecord.CommentCount)
+ xlsx.SetCellValue(sheetName, "G"+rows, userRecord.FocusRepoCount)
+ xlsx.SetCellValue(sheetName, "H"+rows, userRecord.StarRepoCount)
+ xlsx.SetCellValue(sheetName, "I"+rows, userRecord.LoginCount)
+ xlsx.SetCellValue(sheetName, "J"+rows, userRecord.WatchedCount)
+ xlsx.SetCellValue(sheetName, "K"+rows, userRecord.CommitCodeSize)
+ xlsx.SetCellValue(sheetName, "L"+rows, userRecord.SolveIssueCount)
+ xlsx.SetCellValue(sheetName, "M"+rows, userRecord.EncyclopediasCount)
+ xlsx.SetCellValue(sheetName, "N"+rows, userRecord.CreateRepoCount)
+ xlsx.SetCellValue(sheetName, "O"+rows, fmt.Sprintf("%.2f", userRecord.OpenIIndex))
+
+ formatTime := userRecord.RegistDate.Format("2006-01-02 15:04:05")
+ xlsx.SetCellValue(sheetName, "P"+rows, formatTime[0:len(formatTime)-3])
+
+ formatTime = userRecord.DataDate
+ xlsx.SetCellValue(sheetName, "Q"+rows, formatTime+" 00:01")
+ }
+
+ //设置默认打开的表单
+ xlsx.SetActiveSheet(index)
+ filename := sheetName + "_" + ctx.Tr("user.static."+tableName) + ".xlsx"
+ ctx.Resp.Header().Set("Content-Disposition", "attachment; filename="+url.QueryEscape(filename))
+ ctx.Resp.Header().Set("Content-Type", "application/octet-stream")
+ if _, err := xlsx.WriteTo(ctx.Resp); err != nil {
+ log.Info("writer exel error." + err.Error())
+ }
+ indexTotal += PAGE_SIZE
+ if indexTotal >= count {
+ break
+ }
+ }
+ } else {
+ re, count := models.QueryUserStaticDataByTableName((page-1)*pageSize, pageSize, tableName, queryObj, userName)
+ mapInterface := make(map[string]interface{})
+ mapInterface["data"] = re
+ mapInterface["count"] = count
+ ctx.JSON(http.StatusOK, mapInterface)
+ }
+}
+
+func QueryUserStaticCurrentMonth(ctx *context.Context) {
+ queryUserDataPage(ctx, "public.user_business_analysis_current_month", new(models.UserBusinessAnalysisCurrentMonth))
+}
+
+func QueryUserStaticCurrentWeek(ctx *context.Context) {
+ queryUserDataPage(ctx, "public.user_business_analysis_current_week", new(models.UserBusinessAnalysisCurrentWeek))
+}
+
+func QueryUserStaticCurrentYear(ctx *context.Context) {
+ queryUserDataPage(ctx, "public.user_business_analysis_current_year", new(models.UserBusinessAnalysisCurrentYear))
+}
+
+func QueryUserStaticLast30Day(ctx *context.Context) {
+ queryUserDataPage(ctx, "public.user_business_analysis_last30_day", new(models.UserBusinessAnalysisLast30Day))
+}
+
+func QueryUserStaticLastMonth(ctx *context.Context) {
+ queryUserDataPage(ctx, "public.user_business_analysis_last_month", new(models.UserBusinessAnalysisLastMonth))
+}
+
+func QueryUserStaticYesterday(ctx *context.Context) {
+ queryUserDataPage(ctx, "public.user_business_analysis_yesterday", new(models.UserBusinessAnalysisYesterday))
+}
+
+func QueryUserStaticAll(ctx *context.Context) {
+ queryUserDataPage(ctx, "public.user_business_analysis_all", new(models.UserBusinessAnalysisAll))
+}
+
func QueryUserStaticDataPage(ctx *context.Context) {
startDate := ctx.Query("startDate")
endDate := ctx.Query("endDate")
diff --git a/routers/routes/routes.go b/routers/routes/routes.go
index 72dc7a6e1..0d6aa5531 100755
--- a/routers/routes/routes.go
+++ b/routers/routes/routes.go
@@ -970,20 +970,20 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Group("/:jobid", func() {
m.Get("", reqRepoCloudBrainReader, repo.CloudBrainShow)
m.Get("/debug", cloudbrain.AdminOrJobCreaterRight, repo.CloudBrainDebug)
- m.Post("/commit_image", cloudbrain.AdminOrOwnerOrJobCreaterRight, bindIgnErr(auth.CommitImageCloudBrainForm{}), repo.CloudBrainCommitImage)
+ m.Post("/commit_image", cloudbrain.AdminOrJobCreaterRight, bindIgnErr(auth.CommitImageCloudBrainForm{}), repo.CloudBrainCommitImage)
m.Post("/stop", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.CloudBrainStop)
m.Post("/del", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.CloudBrainDel)
- m.Post("/restart", reqRepoCloudBrainWriter, repo.CloudBrainRestart)
+ m.Post("/restart", cloudbrain.AdminOrJobCreaterRight, repo.CloudBrainRestart)
m.Get("/rate", reqRepoCloudBrainReader, repo.GetRate)
m.Get("/models", reqRepoCloudBrainReader, repo.CloudBrainShowModels)
- m.Get("/download_model", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.CloudBrainDownloadModel)
+ m.Get("/download_model", cloudbrain.AdminOrJobCreaterRight, repo.CloudBrainDownloadModel)
})
m.Get("/create", reqRepoCloudBrainWriter, repo.CloudBrainNew)
m.Post("/create", reqRepoCloudBrainWriter, bindIgnErr(auth.CreateCloudBrainForm{}), repo.CloudBrainCreate)
}, context.RepoRef())
m.Group("/modelmanage", func() {
m.Post("/create_model", reqRepoModelManageWriter, repo.SaveModel)
- m.Post("/create_new_model", reqRepoModelManageWriter, repo.SaveNewNameModel)
+ m.Post("/create_new_model", repo.SaveNewNameModel)
m.Delete("/delete_model", repo.DeleteModel)
m.Put("/modify_model", repo.ModifyModelInfo)
m.Get("/show_model", reqRepoModelManageReader, repo.ShowModelTemplate)
@@ -993,6 +993,9 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Get("/show_model_child_api", repo.ShowOneVersionOtherModel)
m.Get("/query_train_job", reqRepoCloudBrainReader, repo.QueryTrainJobList)
m.Get("/query_train_job_version", reqRepoCloudBrainReader, repo.QueryTrainJobVersionList)
+ m.Get("/query_model_for_predict", reqRepoCloudBrainReader, repo.QueryModelListForPredict)
+ m.Get("/query_modelfile_for_predict", reqRepoCloudBrainReader, repo.QueryModelFileForPredict)
+ m.Get("/query_onelevel_modelfile", reqRepoCloudBrainReader, repo.QueryOneLevelModelFile)
m.Group("/:ID", func() {
m.Get("", repo.ShowSingleModel)
m.Get("/downloadsingle", repo.DownloadSingleModelFile)
@@ -1022,7 +1025,7 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Get("", reqRepoCloudBrainReader, repo.TrainJobShow)
m.Post("/stop", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.TrainJobStop)
m.Post("/del", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.TrainJobDel)
- m.Get("/model_download", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.ModelDownload)
+ m.Get("/model_download", cloudbrain.AdminOrJobCreaterRight, repo.ModelDownload)
m.Get("/create_version", cloudbrain.AdminOrJobCreaterRight, repo.TrainJobNewVersion)
m.Post("/create_version", cloudbrain.AdminOrJobCreaterRight, bindIgnErr(auth.CreateModelArtsTrainJobForm{}), repo.TrainJobCreateVersion)
})
diff --git a/services/repository/repository.go b/services/repository/repository.go
index f50b98b64..eafad988e 100644
--- a/services/repository/repository.go
+++ b/services/repository/repository.go
@@ -5,13 +5,12 @@
package repository
import (
- "fmt"
-
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/notification"
repo_module "code.gitea.io/gitea/modules/repository"
pull_service "code.gitea.io/gitea/services/pull"
+ "fmt"
)
// CreateRepository creates a repository for the user/organization.
diff --git a/services/socketwrap/client.go b/services/socketwrap/client.go
index ce8dbb5e8..7d354453c 100644
--- a/services/socketwrap/client.go
+++ b/services/socketwrap/client.go
@@ -14,6 +14,11 @@ type Client struct {
Send chan *models.Action
}
+func (c *Client) Close() {
+ close(c.Send)
+ c.Conn.Close()
+}
+
func (c *Client) WritePump() {
defer func() {
diff --git a/services/socketwrap/clientManager.go b/services/socketwrap/clientManager.go
index ac6ca0bed..eeb496108 100644
--- a/services/socketwrap/clientManager.go
+++ b/services/socketwrap/clientManager.go
@@ -1,11 +1,17 @@
package socketwrap
import (
+ "os"
+ "os/signal"
+ "syscall"
+
"code.gitea.io/gitea/models"
+ "code.gitea.io/gitea/modules/log"
+ "github.com/elliotchance/orderedmap"
)
type ClientsManager struct {
- Clients map[*Client]bool
+ Clients *orderedmap.OrderedMap
Register chan *Client
Unregister chan *Client
}
@@ -14,32 +20,69 @@ func NewClientsManager() *ClientsManager {
return &ClientsManager{
Register: make(chan *Client),
Unregister: make(chan *Client),
- Clients: make(map[*Client]bool),
+ Clients: orderedmap.NewOrderedMap(),
}
}
-var LastTenActionsQueue = NewSyncQueue(10)
+const MaxClients = 100
+
+var LastActionsQueue = NewSyncQueue(15)
func (h *ClientsManager) Run() {
+ initActionQueue()
+ sig := make(chan os.Signal, 1)
+ signal.Notify(sig, os.Interrupt, syscall.SIGTERM)
+ var signalsReceived uint
for {
select {
case client := <-h.Register:
- h.Clients[client] = true
+ h.Clients.Set(client, true)
+ if h.Clients.Len() > MaxClients {
+ h.Clients.Delete(h.Clients.Front().Key)
+ }
+
case client := <-h.Unregister:
- if _, ok := h.Clients[client]; ok {
- delete(h.Clients, client)
+ if _, ok := h.Clients.Get(client); ok {
+ h.Clients.Delete(client)
close(client.Send)
}
case message := <-models.ActionChan:
- LastTenActionsQueue.Push(message)
- for client := range h.Clients {
+ LastActionsQueue.Push(message)
+ for _, client := range h.Clients.Keys() {
select {
- case client.Send <- message:
+ case client.(*Client).Send <- message:
default:
- close(client.Send)
- delete(h.Clients, client)
+ close(client.(*Client).Send)
+ h.Clients.Delete(client)
}
}
+ case s := <-sig:
+ log.Info("received signal", s)
+ signalsReceived++
+ if signalsReceived < 2 {
+ for _, client := range h.Clients.Keys() {
+ h.Clients.Delete(client)
+ client.(*Client).Close()
+ }
+ break
+
+ }
+ }
+ }
+}
+
+func initActionQueue() {
+ actions, err := models.GetLast20PublicFeeds()
+ if err == nil {
+ for i := len(actions) - 1; i >= 0; i-- {
+
+ user, err := models.GetUserByID(actions[i].UserID)
+ if err == nil {
+ if !user.IsOrganization() {
+ LastActionsQueue.Push(actions[i])
+ }
+
+ }
}
}
diff --git a/templates/base/footer_content.tmpl b/templates/base/footer_content.tmpl
index 86ef0d98e..42084b871 100755
--- a/templates/base/footer_content.tmpl
+++ b/templates/base/footer_content.tmpl
@@ -26,7 +26,15 @@
{{end}}