From c802b47c27be15f0b93452e9eaa2fa4c1e01e9dd Mon Sep 17 00:00:00 2001 From: ychao_1983 Date: Fri, 14 Jan 2022 16:56:57 +0800 Subject: [PATCH 01/63] =?UTF-8?q?=E5=8D=83=E6=A0=A1=E8=AE=A1=E5=88=92?= =?UTF-8?q?=E5=90=8E=E7=AB=AF=E4=BB=A3=E7=A0=81=E5=90=88=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- models/repo.go | 75 ++++++++---- models/repo_list.go | 21 ++++ modules/auth/repo_form.go | 12 ++ modules/repository/create.go | 10 +- options/locale/locale_en-US.ini | 8 ++ options/locale/locale_zh-CN.ini | 8 ++ routers/home.go | 65 ++-------- routers/org/home.go | 41 ++++++- routers/org/members.go | 10 +- routers/org/teams.go | 11 +- routers/repo/course.go | 189 ++++++++++++++++++++++++++++++ routers/routes/routes.go | 7 ++ services/repository/repository.go | 83 ++++++++++++- 13 files changed, 447 insertions(+), 93 deletions(-) create mode 100644 routers/repo/course.go diff --git a/models/repo.go b/models/repo.go index 8ba48f7a3a..93e2cb140e 100755 --- a/models/repo.go +++ b/models/repo.go @@ -140,6 +140,7 @@ func NewRepoContext() { // RepositoryStatus defines the status of repository type RepositoryStatus int type RepoBlockChainStatus int +type RepoType int // all kinds of RepositoryStatus const ( @@ -153,6 +154,11 @@ const ( RepoBlockChainFailed ) +const ( + RepoNormal RepoType = iota + RepoCourse +) + // Repository represents a git repository. type Repository struct { ID int64 `xorm:"pk autoincr"` @@ -166,7 +172,8 @@ type Repository struct { OriginalServiceType api.GitServiceType `xorm:"index"` OriginalURL string `xorm:"VARCHAR(2048)"` DefaultBranch string - + CreatorID int64 `xorm:"INDEX NOT NULL DEFAULT 0"` + Creator *User `xorm:"-"` NumWatches int NumStars int NumForks int @@ -175,11 +182,12 @@ type Repository struct { NumOpenIssues int `xorm:"-"` NumPulls int NumClosedPulls int - NumOpenPulls int `xorm:"-"` - NumMilestones int `xorm:"NOT NULL DEFAULT 0"` - NumClosedMilestones int `xorm:"NOT NULL DEFAULT 0"` - NumOpenMilestones int `xorm:"-"` - NumCommit int64 `xorm:"NOT NULL DEFAULT 0"` + NumOpenPulls int `xorm:"-"` + NumMilestones int `xorm:"NOT NULL DEFAULT 0"` + NumClosedMilestones int `xorm:"NOT NULL DEFAULT 0"` + NumOpenMilestones int `xorm:"-"` + NumCommit int64 `xorm:"NOT NULL DEFAULT 0"` + RepoType RepoType `xorm:"NOT NULL DEFAULT 0"` IsPrivate bool `xorm:"INDEX"` IsEmpty bool `xorm:"INDEX"` @@ -1035,6 +1043,8 @@ type CreateRepoOptions struct { IsMirror bool AutoInit bool Status RepositoryStatus + IsCourse bool + Topics []string } // GetRepoInitFile returns repository init files @@ -1080,7 +1090,7 @@ func IsUsableRepoAlias(name string) error { } // CreateRepository creates a repository for the user/organization. -func CreateRepository(ctx DBContext, doer, u *User, repo *Repository) (err error) { +func CreateRepository(ctx DBContext, doer, u *User, repo *Repository, opts ...CreateRepoOptions) (err error) { if err = IsUsableRepoName(repo.Name); err != nil { return err } @@ -1094,7 +1104,10 @@ func CreateRepository(ctx DBContext, doer, u *User, repo *Repository) (err error } else if has { return ErrRepoAlreadyExist{u.Name, repo.Name} } - + isCourse := isCourse(opts) + if isCourse { + repo.CreatorID = doer.ID + } if _, err = ctx.e.Insert(repo); err != nil { return err } @@ -1128,17 +1141,23 @@ func CreateRepository(ctx DBContext, doer, u *User, repo *Repository) (err error Config: &PullRequestsConfig{AllowMerge: true, AllowRebase: true, AllowRebaseMerge: true, AllowSquash: true}, }) } else if tp == UnitTypeDatasets { - units = append(units, RepoUnit{ - RepoID: repo.ID, - Type: tp, - Config: &DatasetConfig{EnableDataset: true}, - }) + if !isCourse { + units = append(units, RepoUnit{ + RepoID: repo.ID, + Type: tp, + Config: &DatasetConfig{EnableDataset: true}, + }) + } + } else if tp == UnitTypeCloudBrain { - units = append(units, RepoUnit{ - RepoID: repo.ID, - Type: tp, - Config: &CloudBrainConfig{EnableCloudBrain: true}, - }) + if !isCourse { + units = append(units, RepoUnit{ + RepoID: repo.ID, + Type: tp, + Config: &CloudBrainConfig{EnableCloudBrain: true}, + }) + } + } else if tp == UnitTypeBlockChain { units = append(units, RepoUnit{ RepoID: repo.ID, @@ -1146,11 +1165,13 @@ func CreateRepository(ctx DBContext, doer, u *User, repo *Repository) (err error Config: &BlockChainConfig{EnableBlockChain: true}, }) } else if tp == UnitTypeModelManage { - units = append(units, RepoUnit{ - RepoID: repo.ID, - Type: tp, - Config: &ModelManageConfig{EnableModelManage: true}, - }) + if !isCourse { + units = append(units, RepoUnit{ + RepoID: repo.ID, + Type: tp, + Config: &ModelManageConfig{EnableModelManage: true}, + }) + } } else { units = append(units, RepoUnit{ RepoID: repo.ID, @@ -1220,6 +1241,14 @@ func CreateRepository(ctx DBContext, doer, u *User, repo *Repository) (err error return nil } +func isCourse(opts []CreateRepoOptions) bool { + var isCourse = false + if len(opts) > 0 { + isCourse = opts[0].IsCourse + } + return isCourse +} + func countRepositories(userID int64, private bool) int64 { sess := x.Where("id > 0") diff --git a/models/repo_list.go b/models/repo_list.go index e41b0f49d8..6fb9380dea 100755 --- a/models/repo_list.go +++ b/models/repo_list.go @@ -48,9 +48,12 @@ func (repos RepositoryList) loadAttributes(e Engine) error { set := make(map[int64]struct{}) repoIDs := make([]int64, len(repos)) + setCreator := make(map[int64]struct{}) for i := range repos { set[repos[i].OwnerID] = struct{}{} repoIDs[i] = repos[i].ID + setCreator[repos[i].CreatorID] = struct{}{} + } // Load owners. @@ -61,8 +64,18 @@ func (repos RepositoryList) loadAttributes(e Engine) error { Find(&users); err != nil { return fmt.Errorf("find users: %v", err) } + //Load creator + creators := make(map[int64]*User, len(set)) + if err := e. + Where("id > 0"). + In("id", keysInt64(setCreator)). + Find(&creators); err != nil { + return fmt.Errorf("find create repo users: %v", err) + } + for i := range repos { repos[i].Owner = users[repos[i].OwnerID] + repos[i].Creator = creators[repos[i].CreatorID] } // Load primary language. @@ -174,6 +187,10 @@ type SearchRepoOptions struct { // True -> include just has milestones // False -> include just has no milestone HasMilestones util.OptionalBool + // None -> include all repos + // True -> include just courses + // False -> include just no courses + Course util.OptionalBool } //SearchOrderBy is used to sort the result @@ -351,6 +368,10 @@ func SearchRepositoryCondition(opts *SearchRepoOptions) builder.Cond { cond = cond.And(builder.Eq{"is_mirror": opts.Mirror == util.OptionalBoolTrue}) } + if opts.Course == util.OptionalBoolTrue { + cond = cond.And(builder.Eq{"repo_type": RepoCourse}) + } + if opts.Actor != nil && opts.Actor.IsRestricted { cond = cond.And(accessibleRepositoryCondition(opts.Actor)) } diff --git a/modules/auth/repo_form.go b/modules/auth/repo_form.go index 32890a5c1e..c113aa8902 100755 --- a/modules/auth/repo_form.go +++ b/modules/auth/repo_form.go @@ -728,3 +728,15 @@ type DeadlineForm struct { func (f *DeadlineForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { return validate(errs, ctx.Data, f, ctx.Locale) } + +type CreateCourseForm struct { + RepoName string `binding:"Required;AlphaDashDot;MaxSize(100)"` + Alias string `binding:"Required;MaxSize(100);AlphaDashDotChinese"` + Topics string + Description string `binding:"MaxSize(1024)"` +} + +// Validate validates the fields +func (f *CreateCourseForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { + return validate(errs, ctx.Data, f, ctx.Locale) +} diff --git a/modules/repository/create.go b/modules/repository/create.go index f5dfa63d67..2a24cb7086 100644 --- a/modules/repository/create.go +++ b/modules/repository/create.go @@ -22,6 +22,10 @@ func CreateRepository(doer, u *models.User, opts models.CreateRepoOptions) (_ *m Limit: u.MaxRepoCreation, } } + var RepoType = models.RepoNormal + if opts.IsCourse { + RepoType = models.RepoCourse + } repo := &models.Repository{ OwnerID: u.ID, @@ -38,10 +42,14 @@ func CreateRepository(doer, u *models.User, opts models.CreateRepoOptions) (_ *m CloseIssuesViaCommitInAnyBranch: setting.Repository.DefaultCloseIssuesViaCommitsInAnyBranch, Status: opts.Status, IsEmpty: !opts.AutoInit, + RepoType: RepoType, } err = models.WithTx(func(ctx models.DBContext) error { - if err = models.CreateRepository(ctx, doer, u, repo); err != nil { + if err = models.CreateRepository(ctx, doer, u, repo, opts); err != nil { + return err + } + if err = models.SaveTopics(repo.ID, opts.Topics...); err != nil { return err } diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 0b3bb1792b..1756b9533d 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -50,6 +50,7 @@ repository = Repository organization = Organization mirror = Mirror new_repo = New Repository +new_course=Publish Course new_migrate = New Migration new_dataset = New Dataset edit_dataset = Edit Dataset @@ -390,6 +391,7 @@ lang_select_error = Select a language from the list. username_been_taken = The username is already taken. repo_name_been_taken = The repository name or path is already used. +course_name_been_taken=The course path is already used. visit_rate_limit = Remote visit addressed rate limitation. 2fa_auth_required = Remote visit required two factors authentication. org_name_been_taken = The organization name is already taken. @@ -802,6 +804,8 @@ readme = README readme_helper = Select a README file template. auto_init = Initialize Repository (Adds .gitignore, License and README) create_repo = Create Repository +create_course = Publish Course +failed_to_create_course=Fail to publish course, please try again later. default_branch = Default Branch mirror_prune = Prune mirror_prune_desc = Remove obsolete remote-tracking references @@ -968,8 +972,12 @@ archive.issue.nocomment = This repo is archived. You cannot comment on issues. archive.pull.nocomment = This repo is archived. You cannot comment on pull requests. form.reach_limit_of_creation = You have already reached your limit of %d repositories. +form.reach_limit_of_course_creation=You have already reached your limit of %d courses or repositories. form.name_reserved = The repository name '%s' is reserved. +form.course_name_reserved=The course name '%s' is reserved. form.name_pattern_not_allowed = The pattern '%s' is not allowed in a repository name. +form.course_name_pattern_not_allowed=The pattern '%s' is not allowed in a course name. +add_course_org_fail=Fail to add organization, please try again later. need_auth = Clone Authorization migrate_type = Migration Type diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini index d5eac032b1..d034b17220 100755 --- a/options/locale/locale_zh-CN.ini +++ b/options/locale/locale_zh-CN.ini @@ -50,6 +50,7 @@ repository=项目 organization=组织 mirror=镜像 new_repo=创建项目 +new_course=发布课程 new_dataset=创建数据集 new_migrate=迁移外部项目 edit_dataset = Edit Dataset @@ -395,6 +396,7 @@ lang_select_error=从列表中选出语言 username_been_taken=用户名已被使用。 repo_name_been_taken=项目名称或项目路径已被使用。 +course_name_been_taken=课程名称或路径已被使用。 visit_rate_limit=远程访问达到速度限制。 2fa_auth_required=远程访问需要双重验证。 org_name_been_taken=组织名称已被使用。 @@ -808,6 +810,8 @@ readme=自述 readme_helper=选择自述文件模板。 auto_init=初始化存储库 (添加. gitignore、许可证和自述文件) create_repo=创建项目 +create_course=发布课程 +failed_to_create_course=发布课程失败,请稍后再试。 default_branch=默认分支 mirror_prune=修剪 mirror_prune_desc=删除过时的远程跟踪引用 @@ -980,8 +984,12 @@ archive.issue.nocomment=此项目已存档,您不能在此任务添加评论 archive.pull.nocomment=此项目已存档,您不能在此合并请求添加评论。 form.reach_limit_of_creation=你已经达到了您的 %d 项目的限制。 +form.reach_limit_of_course_creation=你已经达到了您的 %d 课程的限制。 form.name_reserved=项目名称 '%s' 是被保留的。 +form.course_name_reserved=课程名称 '%s' 是被保留的。 form.name_pattern_not_allowed=项目名称中不允许使用模式 "%s"。 +form.course_name_pattern_not_allowed=课程名称中不允许使用模式 "%s"。 +add_course_org_fail=加入组织失败,请稍后重试。 need_auth=需要授权验证 migrate_type=迁移类型 diff --git a/routers/home.go b/routers/home.go index 24de1a10c2..397e1990dd 100755 --- a/routers/home.go +++ b/routers/home.go @@ -7,11 +7,11 @@ package routers import ( "bytes" - "fmt" - "io/ioutil" "net/http" "strings" + "code.gitea.io/gitea/services/repository" + "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" @@ -133,6 +133,7 @@ type RepoSearchOptions struct { Restricted bool PageSize int TplName base.TplName + Course util.OptionalBool } var ( @@ -211,6 +212,7 @@ func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) { AllLimited: true, TopicName: topic, IncludeDescription: setting.UI.SearchRepoDescription, + Course: opts.Course, }) if err != nil { ctx.ServerError("SearchRepository", err) @@ -559,7 +561,7 @@ func NotFound(ctx *context.Context) { func RecommendOrgFromPromote(ctx *context.Context) { url := setting.RecommentRepoAddr + "organizations" - result, err := recommendFromPromote(url) + result, err := repository.RecommendFromPromote(url) if err != nil { ctx.ServerError("500", err) return @@ -586,62 +588,11 @@ func RecommendOrgFromPromote(ctx *context.Context) { ctx.JSON(200, resultOrg) } -func recommendFromPromote(url string) ([]string, error) { - resp, err := http.Get(url) - if err != nil || resp.StatusCode != 200 { - log.Info("Get organizations url error=" + err.Error()) - return nil, err - } - bytes, err := ioutil.ReadAll(resp.Body) - resp.Body.Close() - if err != nil { - log.Info("Get organizations url error=" + err.Error()) - return nil, err - } - - allLineStr := string(bytes) - lines := strings.Split(allLineStr, "\n") - result := make([]string, len(lines)) - for i, line := range lines { - log.Info("i=" + fmt.Sprint(i) + " line=" + line) - result[i] = strings.Trim(line, " ") - } - return result, nil -} - func RecommendRepoFromPromote(ctx *context.Context) { - url := setting.RecommentRepoAddr + "projects" - result, err := recommendFromPromote(url) + result, err := repository.GetRecommendRepoFromPromote("projects") 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()) - } - } + } else { + ctx.JSON(200, result) } - ctx.JSON(200, resultRepo) } diff --git a/routers/org/home.go b/routers/org/home.go index df600d96d7..4c350d352f 100755 --- a/routers/org/home.go +++ b/routers/org/home.go @@ -7,6 +7,10 @@ package org import ( "strings" + "code.gitea.io/gitea/services/repository" + + "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" @@ -14,7 +18,8 @@ import ( ) const ( - tplOrgHome base.TplName = "org/home" + tplOrgHome base.TplName = "org/home" + tplOrgCourseHome base.TplName = "org/home_courses" ) // Home show organization home page @@ -59,10 +64,16 @@ func Home(ctx *context.Context) { case "fewestforks": orderBy = models.SearchOrderByForks default: - ctx.Data["SortType"] = "recentupdate" - orderBy = models.SearchOrderByRecentUpdated - } + if setting.Course.OrgName == org.Name { + ctx.Data["SortType"] = "newest" + orderBy = models.SearchOrderByNewest + } else { + ctx.Data["SortType"] = "recentupdate" + orderBy = models.SearchOrderByRecentUpdated + } + } + orderBy = orderBy + ",id" keyword := strings.Trim(ctx.Query("q"), " ") ctx.Data["Keyword"] = keyword @@ -76,9 +87,21 @@ func Home(ctx *context.Context) { count int64 err error ) + pageSize := setting.UI.User.RepoPagingNum + var CourseOptional util.OptionalBool = util.OptionalBoolNone + if setting.Course.OrgName == org.Name { + pageSize = 15 + CourseOptional = util.OptionalBoolTrue + recommendCourses, _ := repository.GetRecommendRepoFromPromote("courses") + ctx.Data["RecommendCourses"] = recommendCourses + recommendCourseKeyWords, _ := repository.GetRecommendCourseKeyWords() + ctx.Data["CoursesKeywords"] = recommendCourseKeyWords + + } + repos, count, err = models.SearchRepository(&models.SearchRepoOptions{ ListOptions: models.ListOptions{ - PageSize: setting.UI.User.RepoPagingNum, + PageSize: pageSize, Page: page, }, Keyword: keyword, @@ -87,6 +110,7 @@ func Home(ctx *context.Context) { Private: ctx.IsSigned, Actor: ctx.User, IncludeDescription: setting.UI.SearchRepoDescription, + Course: CourseOptional, }) if err != nil { ctx.ServerError("SearchRepository", err) @@ -138,5 +162,10 @@ func Home(ctx *context.Context) { } ctx.Data["tags"] = tags - ctx.HTML(200, tplOrgHome) + if setting.Course.OrgName == org.Name { + ctx.HTML(200, tplOrgCourseHome) + } else { + ctx.HTML(200, tplOrgHome) + } + } diff --git a/routers/org/members.go b/routers/org/members.go index 9f13d1be3f..39df692d27 100755 --- a/routers/org/members.go +++ b/routers/org/members.go @@ -17,7 +17,8 @@ import ( const ( // tplMembers template for organization members page - tplMembers base.TplName = "org/member/members" + tplMembers base.TplName = "org/member/members" + tplCourseMembers base.TplName = "org/member/course_members" ) // Members render organization users page @@ -64,8 +65,11 @@ func Members(ctx *context.Context) { ctx.Data["MembersIsPublicMember"] = membersIsPublic ctx.Data["MembersIsUserOrgOwner"] = members.IsUserOrgOwner(org.ID) ctx.Data["MembersTwoFaStatus"] = members.GetTwoFaStatus() - - ctx.HTML(200, tplMembers) + if setting.Course.OrgName == org.Name { + ctx.HTML(200, tplCourseMembers) + } else { + ctx.HTML(200, tplMembers) + } } // MembersAction response for operation to a member of organization diff --git a/routers/org/teams.go b/routers/org/teams.go index 03fbf068da..8aa3e39473 100644 --- a/routers/org/teams.go +++ b/routers/org/teams.go @@ -10,6 +10,8 @@ import ( "path" "strings" + "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/base" @@ -22,7 +24,8 @@ import ( const ( // tplTeams template path for teams list page - tplTeams base.TplName = "org/team/teams" + tplTeams base.TplName = "org/team/teams" + tplCourseTeams base.TplName = "org/team/courseTeams" // tplTeamNew template path for create new team page tplTeamNew base.TplName = "org/team/new" // tplTeamMembers template path for showing team members page @@ -44,8 +47,12 @@ func Teams(ctx *context.Context) { } } ctx.Data["Teams"] = org.Teams + if setting.Course.OrgName == org.Name { + ctx.HTML(200, tplCourseTeams) + } else { + ctx.HTML(200, tplTeams) + } - ctx.HTML(200, tplTeams) } // TeamsAction response for join, leave, remove, add operations to team diff --git a/routers/repo/course.go b/routers/repo/course.go new file mode 100644 index 0000000000..b8f39817b0 --- /dev/null +++ b/routers/repo/course.go @@ -0,0 +1,189 @@ +package repo + +import ( + "net/http" + "strings" + + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/auth" + "code.gitea.io/gitea/modules/base" + "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/setting" + repo_service "code.gitea.io/gitea/services/repository" +) + +const ( + tplCreateCourse base.TplName = "repo/createCourse" +) + +func CreateCourse(ctx *context.Context) { + ctx.Data["Title"] = ctx.Tr("new_course") + + ctx.Data["Owner"] = setting.Course.OrgName + + ctx.HTML(200, tplCreateCourse) + +} + +func CreateCoursePost(ctx *context.Context, form auth.CreateCourseForm) { + ctx.Data["Title"] = ctx.Tr("new_course") + + if ctx.Written() { + return + } + + var topics = make([]string, 0) + var topicsStr = strings.TrimSpace(form.Topics) + if len(topicsStr) > 0 { + topics = strings.Split(topicsStr, ",") + } + + validTopics, invalidTopics := models.SanitizeAndValidateTopics(topics) + + if len(validTopics) > 25 { + ctx.RenderWithErr(ctx.Tr("repo.topic.count_prompt"), tplCreateCourse, form) + return + } + + if len(invalidTopics) > 0 { + ctx.RenderWithErr(ctx.Tr("repo.topic.format_prompt"), tplCreateCourse, form) + return + } + + var repo *models.Repository + var err error + + if setting.Course.OrgName == "" || setting.Course.TeamName == "" { + log.Error("then organization name or team name of course is empty.") + ctx.RenderWithErr(ctx.Tr("repo.failed_to_create_course"), tplCreateCourse, form) + return + } + + org, team, err := getOrgAndTeam() + + if err != nil { + log.Error("Failed to get team from db.", err) + ctx.RenderWithErr(ctx.Tr("repo.failed_to_create_course"), tplCreateCourse, form) + return + } + isInTeam, err := models.IsUserInTeams(ctx.User.ID, []int64{team.ID}) + if err != nil { + log.Error("Failed to get user in team from db.") + ctx.RenderWithErr(ctx.Tr("repo.failed_to_create_course"), tplCreateCourse, form) + return + } + + if !isInTeam { + err = models.AddTeamMember(team, ctx.User.ID) + if err != nil { + log.Error("Failed to add user to team.") + ctx.RenderWithErr(ctx.Tr("repo.failed_to_create_course"), tplCreateCourse, form) + return + } + } + + if ctx.HasError() { + ctx.HTML(200, tplCreateCourse) + return + } + + repo, err = repo_service.CreateRepository(ctx.User, org, models.CreateRepoOptions{ + Name: form.RepoName, + Alias: form.Alias, + Description: form.Description, + Gitignores: "", + IssueLabels: "", + License: "", + Readme: "Default", + IsPrivate: false, + DefaultBranch: "master", + AutoInit: true, + IsCourse: true, + Topics: validTopics, + }) + if err == nil { + log.Trace("Repository created [%d]: %s/%s", repo.ID, org.Name, repo.Name) + ctx.Redirect(setting.AppSubURL + "/" + org.Name + "/" + repo.Name) + return + } + + handleCreateCourseError(ctx, org, err, "CreateCoursePost", tplCreateCourse, &form) +} + +func AddCourseOrg(ctx *context.Context) { + + _, team, err := getOrgAndTeam() + + if err != nil { + log.Error("Failed to get team from db.", err) + ctx.JSON(http.StatusOK, map[string]interface{}{ + "code": 1, + "message": ctx.Tr("repo.addCourseOrgFail"), + }) + return + } + isInTeam, err := models.IsUserInTeams(ctx.User.ID, []int64{team.ID}) + if err != nil { + log.Error("Failed to get user in team from db.", err) + ctx.JSON(http.StatusOK, map[string]interface{}{ + "code": 1, + "message": ctx.Tr("repo.add_course_org_fail"), + }) + return + } + + if !isInTeam { + err = models.AddTeamMember(team, ctx.User.ID) + if err != nil { + log.Error("Failed to add user to team.", err) + ctx.JSON(http.StatusOK, map[string]interface{}{ + "code": 1, + "message": ctx.Tr("repo.add_course_org_fail"), + }) + return + } + } + + ctx.JSON(http.StatusOK, map[string]interface{}{ + "code": 0, + "message": "", + }) + +} + +func getOrgAndTeam() (*models.User, *models.Team, error) { + org, err := models.GetUserByName(setting.Course.OrgName) + + if err != nil { + log.Error("Failed to get organization from db.", err) + return nil, nil, err + } + + team, err := models.GetTeam(org.ID, setting.Course.TeamName) + + if err != nil { + log.Error("Failed to get team from db.", err) + + return nil, nil, err + } + return org, team, nil +} + +func handleCreateCourseError(ctx *context.Context, owner *models.User, err error, name string, tpl base.TplName, form interface{}) { + switch { + case models.IsErrReachLimitOfRepo(err): + ctx.RenderWithErr(ctx.Tr("repo.form.reach_limit_of_course_creation", owner.MaxCreationLimit()), tpl, form) + case models.IsErrRepoAlreadyExist(err): + ctx.Data["Err_RepoName"] = true + ctx.RenderWithErr(ctx.Tr("form.course_name_been_taken"), tpl, form) + case models.IsErrNameReserved(err): + ctx.Data["Err_RepoName"] = true + ctx.RenderWithErr(ctx.Tr("repo.form.course_name_reserved", err.(models.ErrNameReserved).Name), tpl, form) + case models.IsErrNamePatternNotAllowed(err): + ctx.Data["Err_RepoName"] = true + ctx.RenderWithErr(ctx.Tr("repo.form.course_name_pattern_not_allowed", err.(models.ErrNamePatternNotAllowed).Pattern), tpl, form) + default: + ctx.ServerError(name, err) + } +} diff --git a/routers/routes/routes.go b/routers/routes/routes.go index 0d6aa5531b..5f2237dd89 100755 --- a/routers/routes/routes.go +++ b/routers/routes/routes.go @@ -708,6 +708,13 @@ func RegisterRoutes(m *macaron.Macaron) { }, reqSignIn) // ***** END: Organization ***** + m.Group("/course", func() { + m.Get("/create", repo.CreateCourse) + m.Post("/create", bindIgnErr(auth.CreateCourseForm{}), repo.CreateCoursePost) + m.Get("/addOrg", repo.AddCourseOrg) + + }, reqSignIn) + // ***** START: Repository ***** m.Group("/repo", func() { m.Get("/create", repo.Create) diff --git a/services/repository/repository.go b/services/repository/repository.go index dffa1ba11b..86ee9370ef 100644 --- a/services/repository/repository.go +++ b/services/repository/repository.go @@ -5,12 +5,17 @@ package repository import ( + "fmt" + "io/ioutil" + "net/http" + "strings" + "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" + "code.gitea.io/gitea/modules/setting" pull_service "code.gitea.io/gitea/services/pull" - "fmt" ) // CreateRepository creates a repository for the user/organization. @@ -86,3 +91,79 @@ func PushCreateRepo(authUser, owner *models.User, repoName string) (*models.Repo return repo, nil } + +func GetRecommendCourseKeyWords() ([]string, error) { + + url := setting.RecommentRepoAddr + "course_keywords" + result, err := RecommendFromPromote(url) + + if err != nil { + return []string{}, err + } + return result, err + +} + +func GetRecommendRepoFromPromote(filename string) ([]map[string]interface{}, error) { + resultRepo := make([]map[string]interface{}, 0) + url := setting.RecommentRepoAddr + filename + result, err := RecommendFromPromote(url) + + if err != nil { + + return resultRepo, err + } + + //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["Alias"] = repo.Alias + repoMap["Creator"] = repo.Creator + 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()) + } + } + } + return resultRepo, nil +} + +func RecommendFromPromote(url string) ([]string, error) { + resp, err := http.Get(url) + if err != nil || resp.StatusCode != 200 { + log.Info("Get organizations url error=" + err.Error()) + return nil, err + } + bytes, err := ioutil.ReadAll(resp.Body) + resp.Body.Close() + if err != nil { + log.Info("Get organizations url error=" + err.Error()) + return nil, err + } + + allLineStr := string(bytes) + lines := strings.Split(allLineStr, "\n") + result := make([]string, len(lines)) + for i, line := range lines { + log.Info("i=" + fmt.Sprint(i) + " line=" + line) + result[i] = strings.Trim(line, " ") + } + return result, nil +} -- 2.34.1 From 110fb5cbc0b5b65608613ba7c2f40882d74a6cb0 Mon Sep 17 00:00:00 2001 From: ychao_1983 Date: Fri, 14 Jan 2022 17:16:44 +0800 Subject: [PATCH 02/63] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/setting/setting.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/modules/setting/setting.go b/modules/setting/setting.go index e7ab0b7d26..3d2bd91c58 100755 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -568,6 +568,11 @@ var ( }{} Warn_Notify_Mails []string + + Course = struct { + OrgName string + TeamName string + }{} ) // DateLang transforms standard language locale name to corresponding value in datetime plugin. @@ -1331,6 +1336,10 @@ func NewContext() { sec = Cfg.Section("warn_mail") Warn_Notify_Mails = strings.Split(sec.Key("mails").MustString(""), ",") + + sec = Cfg.Section("course") + Course.OrgName = sec.Key("org_name").MustString("") + Course.TeamName = sec.Key("team_name").MustString("") } func SetRadarMapConfig() { -- 2.34.1 From 05eb0a31a91cd62269496cc5e4858627df012b76 Mon Sep 17 00:00:00 2001 From: ychao_1983 Date: Mon, 17 Jan 2022 15:25:13 +0800 Subject: [PATCH 03/63] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- models/repo.go | 13 +++++++++++++ services/repository/repository.go | 7 ++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/models/repo.go b/models/repo.go index 93e2cb140e..964bf7c363 100755 --- a/models/repo.go +++ b/models/repo.go @@ -572,6 +572,19 @@ func (repo *Repository) GetOwner() error { return repo.getOwner(x) } +func (repo *Repository) getCreator(e Engine) (err error) { + if repo.CreatorID == 0 { + return nil + } + + repo.Creator, err = getUserByID(e, repo.CreatorID) + return err +} + +func (repo *Repository) GetCreator() error { + return repo.getCreator(x) +} + func (repo *Repository) mustOwner(e Engine) *User { if err := repo.getOwner(e); err != nil { return &User{ diff --git a/services/repository/repository.go b/services/repository/repository.go index 86ee9370ef..f43a3c62df 100644 --- a/services/repository/repository.go +++ b/services/repository/repository.go @@ -128,7 +128,12 @@ func GetRecommendRepoFromPromote(filename string) ([]map[string]interface{}, err repoMap["ID"] = fmt.Sprint(repo.ID) repoMap["Name"] = repo.Name repoMap["Alias"] = repo.Alias - repoMap["Creator"] = repo.Creator + if repo.RepoType == models.RepoCourse { + //Load creator + repo.GetCreator() + repoMap["Creator"] = repo.Creator + } + repoMap["OwnerName"] = repo.OwnerName repoMap["NumStars"] = repo.NumStars repoMap["NumForks"] = repo.NumForks -- 2.34.1 From 6f8ad46c12fc274d0ba5afe60259caca1774cee0 Mon Sep 17 00:00:00 2001 From: ychao_1983 Date: Mon, 17 Jan 2022 16:30:51 +0800 Subject: [PATCH 04/63] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- routers/repo/course.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/routers/repo/course.go b/routers/repo/course.go index b8f39817b0..013ee20da0 100644 --- a/routers/repo/course.go +++ b/routers/repo/course.go @@ -19,8 +19,9 @@ const ( func CreateCourse(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("new_course") + org, _ := models.GetUserByName(setting.Course.OrgName) - ctx.Data["Owner"] = setting.Course.OrgName + ctx.Data["Owner"] = org ctx.HTML(200, tplCreateCourse) -- 2.34.1 From 3f2c50e27156d754be2429816606c23f61173782 Mon Sep 17 00:00:00 2001 From: zhoupzh Date: Mon, 17 Jan 2022 16:36:28 +0800 Subject: [PATCH 05/63] fix issue --- options/locale/locale_en-US.ini | 2 + options/locale/locale_zh-CN.ini | 3 + templates/repo/createCourse.tmpl | 98 ++++++++++++++++++++++++++++++++ 3 files changed, 103 insertions(+) create mode 100644 templates/repo/createCourse.tmpl diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 1756b9533d..17f639866f 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -348,6 +348,8 @@ modify = Update [form] UserName = Username Alias = Repository name +courseAlias = Course Name +courseAdress = Course Path RepoPath = Repository path RepoAdress = Repository Adress Email = Email address diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini index d034b17220..93afc66c40 100755 --- a/options/locale/locale_zh-CN.ini +++ b/options/locale/locale_zh-CN.ini @@ -353,6 +353,8 @@ modify=更新 UserName=用户名 RepoName=项目路径 Alias=项目名称 +courseAlias=课程名称 +courseAdress=课程地址 RepoPath=项目路径 RepoAdress=项目地址 Email=邮箱地址 @@ -802,6 +804,7 @@ generate_from=生成自 repo_desc=项目描述 repo_lang=项目语言 repo_gitignore_helper=选择 .gitignore 模板。 +repo_label_helpe=输入完成后回车键完成标签确定。 issue_labels=任务标签 issue_labels_helper=选择一个任务标签集 license=授权许可 diff --git a/templates/repo/createCourse.tmpl b/templates/repo/createCourse.tmpl new file mode 100644 index 0000000000..5ce7d010b2 --- /dev/null +++ b/templates/repo/createCourse.tmpl @@ -0,0 +1,98 @@ +{{template "base/head" .}} +
+
+
+
+ {{.CsrfTokenHtml}} +

+ {{.i18n.Tr "new_course"}} +

+
+ {{template "base/alert" .}} +
+ + + {{.i18n.Tr "form.reponame_dash_dot_error"}} +
+ +
+ +
+ +
+
/
+
+ +
+
+ {{.i18n.Tr "form.repoadd_dash_dot_error"}} + + +
+ + +
+ +
+ + +
+
+ + + {{.i18n.Tr "cancel"}} +
+
+
+
+
+
+{{template "base/footer" .}} + + \ No newline at end of file -- 2.34.1 From e3d6399311dfb712619ef0aad251143e439e21c7 Mon Sep 17 00:00:00 2001 From: wangjr Date: Mon, 17 Jan 2022 16:58:10 +0800 Subject: [PATCH 06/63] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=8D=83=E6=A0=A1?= =?UTF-8?q?=E4=B8=BB=E9=A1=B5=E5=86=85=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- options/locale/locale_zh-CN.ini | 4 + templates/org/course_list.tmpl | 334 ++++++++++++++++ templates/org/home_courses.tmpl | 479 +++++++++++++++++++++++ templates/org/member/course_members.tmpl | 0 templates/org/team/courseTeams.tmpl | 0 5 files changed, 817 insertions(+) create mode 100644 templates/org/course_list.tmpl create mode 100644 templates/org/home_courses.tmpl create mode 100644 templates/org/member/course_members.tmpl create mode 100644 templates/org/team/courseTeams.tmpl diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini index d034b17220..5180eadaab 100755 --- a/options/locale/locale_zh-CN.ini +++ b/options/locale/locale_zh-CN.ini @@ -2050,6 +2050,7 @@ team_access_desc=项目权限 team_permission_desc=权限 team_unit_desc=允许访问项目单元 team_unit_disabled=(已禁用) +selected_couse=精选课程 form.name_reserved=组织名称 '%s' 是被保留的。 form.name_pattern_not_allowed=组织名称中不允许使用 "%s"。 @@ -2136,6 +2137,9 @@ teams.all_repositories_read_permission_desc=此团队授予读取修改所有项目的访问权限: 成员可以查看和推送至项目。 teams.all_repositories_admin_permission_desc=该团队拥有 管理 所有项目的权限:团队成员可以读取、克隆、推送以及添加其它项目协作者。 +teams.join_teams=加入该组织 + + [admin] dashboard=管理面板 users=帐户管理 diff --git a/templates/org/course_list.tmpl b/templates/org/course_list.tmpl new file mode 100644 index 0000000000..a371ec4ffe --- /dev/null +++ b/templates/org/course_list.tmpl @@ -0,0 +1,334 @@ + +
+ + +
+ +
+ {{range .Repos}} +
+ +
+
+ {{if .Topics }} +
+ {{range .Topics}} + {{if ne . "" }}{{.}}{{end}} + {{end}} + +
+ {{end}} + +
+ + + +
+ {{.Description}} + +
+ + + + +
+
+

+ {{$.i18n.Tr "org.repo_updated"}}{{.CreatedUnix.FormatShort}} {{TimeSinceUnix .UpdatedUnix $.i18n.Lang}} + +

+ +
+
+ {{end}} +
+ +
+ +
+ + + + \ No newline at end of file diff --git a/templates/org/home_courses.tmpl b/templates/org/home_courses.tmpl new file mode 100644 index 0000000000..0f9b70f673 --- /dev/null +++ b/templates/org/home_courses.tmpl @@ -0,0 +1,479 @@ + +{{template "base/head" .}} +
+ {{/* overflow: auto is the clearfix - this avoids the image going beyond + the container where it is supposed to stay inside. */}} + + +
+
+ +
+
+ {{.Org.DisplayName}} + +
+
+ {{if .Org.Description}}

{{.Org.Description}}

{{end}} +
+ +
+ {{if .Org.Location}}
{{svg "octicon-location" 16}} {{.Org.Location}}
{{end}} + {{if .Org.Website}}
{{svg "octicon-link" 16}} {{.Org.Website}}
{{end}} +
+
+
+ + +
+ + +
+ + +
+ +
+
+
+ 全部关键字 + {{range .CoursesKeywords}} + {{.}} + {{end}} +
+ + +
+
+
+ + + +
+ +
+
+
+ + {{template "org/course_list" .}} + {{template "base/paginate" .}} +
+ +
+ +

+ {{.i18n.Tr "org.selected_couse"}} + + + + +

+ +
+ {{range $i, $v := .RecommendCourses}} + + {{if gt $i 0}} +
+ {{end}} +
+ +
+ {{.Alias}} +

+ 贡献者:{{.Creator.Name}} +

+
+
+ + {{end}} + + +
+ + +

+ {{.i18n.Tr "org.people"}} + + + + +

+
+ {{$isMember := .IsOrganizationMember}} + {{range .Members}} + {{if or $isMember (.IsPublicMember $.Org.ID)}} + + {{end}} + {{end}} + + +
+ + {{if .IsOrganizationMember}} +
+ {{.i18n.Tr "org.teams"}} + +
+ + {{if .IsOrganizationOwner}} + + {{end}} + {{end}} +
+
+
+ +
+
+
+ + + +{{template "base/footer" .}} + \ No newline at end of file diff --git a/templates/org/member/course_members.tmpl b/templates/org/member/course_members.tmpl new file mode 100644 index 0000000000..e69de29bb2 diff --git a/templates/org/team/courseTeams.tmpl b/templates/org/team/courseTeams.tmpl new file mode 100644 index 0000000000..e69de29bb2 -- 2.34.1 From c7ae3915aeea63c50b55c95d81099b38695c0636 Mon Sep 17 00:00:00 2001 From: ychao_1983 Date: Mon, 17 Jan 2022 17:00:50 +0800 Subject: [PATCH 07/63] =?UTF-8?q?=E5=8E=BB=E6=8E=89=E6=8E=A8=E8=8D=90?= =?UTF-8?q?=E8=AF=BE=E7=A8=8B=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- routers/org/home.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/routers/org/home.go b/routers/org/home.go index 4c350d352f..b6fda5332d 100755 --- a/routers/org/home.go +++ b/routers/org/home.go @@ -92,8 +92,6 @@ func Home(ctx *context.Context) { if setting.Course.OrgName == org.Name { pageSize = 15 CourseOptional = util.OptionalBoolTrue - recommendCourses, _ := repository.GetRecommendRepoFromPromote("courses") - ctx.Data["RecommendCourses"] = recommendCourses recommendCourseKeyWords, _ := repository.GetRecommendCourseKeyWords() ctx.Data["CoursesKeywords"] = recommendCourseKeyWords -- 2.34.1 From 4ae27f6cfa14b4db383bbc9c94f4ee05de712087 Mon Sep 17 00:00:00 2001 From: zhoupzh Date: Mon, 17 Jan 2022 17:09:20 +0800 Subject: [PATCH 08/63] fix issue --- templates/org/home_courses.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/org/home_courses.tmpl b/templates/org/home_courses.tmpl index 0f9b70f673..e48a3db2c8 100644 --- a/templates/org/home_courses.tmpl +++ b/templates/org/home_courses.tmpl @@ -157,7 +157,7 @@ -- 2.34.1 From 1ec4576ac83923496f205a3abd6dfc309d9d2c9a Mon Sep 17 00:00:00 2001 From: zhoupzh Date: Mon, 17 Jan 2022 17:45:01 +0800 Subject: [PATCH 09/63] fix issue --- options/locale/locale_en-US.ini | 1 + templates/repo/createCourse.tmpl | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 9eb99cb692..d1dac2d3a2 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -798,6 +798,7 @@ generate_from = Generate From repo_desc = Description repo_lang = Language repo_gitignore_helper = Select .gitignore templates. +repo_label_helpe = After the input is completed, press the Enter key to complete the label determination. issue_labels = Issue Labels issue_labels_helper = Select an issue label set. license = License diff --git a/templates/repo/createCourse.tmpl b/templates/repo/createCourse.tmpl index 5ce7d010b2..d2a77eea9a 100644 --- a/templates/repo/createCourse.tmpl +++ b/templates/repo/createCourse.tmpl @@ -11,7 +11,7 @@ {{template "base/alert" .}}
- + {{.i18n.Tr "form.reponame_dash_dot_error"}}
@@ -28,7 +28,7 @@
/
- +
{{.i18n.Tr "form.repoadd_dash_dot_error"}} @@ -40,7 +40,7 @@
-
+
{{ range .tags}} {{if eq .TagName "精选项目"}} @@ -232,7 +220,7 @@
-

+

{{.i18n.Tr "org.people"}}

-
+
{{$isMember := .IsOrganizationMember}} {{range .Members}} {{if or $isMember (.IsPublicMember $.Org.ID)}} @@ -255,13 +243,13 @@
{{if .IsOrganizationMember}} -
+ -
+
{{range .Teams}}
{{.Name}} @@ -273,7 +261,7 @@ {{end}}
{{if .IsOrganizationOwner}} -
+ {{end}} diff --git a/templates/org/member/course_members.tmpl b/templates/org/member/course_members.tmpl index 87189c0157..74a2e4b7c9 100644 --- a/templates/org/member/course_members.tmpl +++ b/templates/org/member/course_members.tmpl @@ -1,9 +1,16 @@ + + {{template "base/head" .}}
{{template "org/header" .}} + {{template "org/navber_course" .}}
{{template "base/alert" .}} - {{template "org/navber" .}}
@@ -67,6 +74,27 @@
{{end}}
+ + {{template "base/paginate" .}}
diff --git a/templates/org/navber_course.tmpl b/templates/org/navber_course.tmpl new file mode 100644 index 0000000000..4bd5084821 --- /dev/null +++ b/templates/org/navber_course.tmpl @@ -0,0 +1,28 @@ + + \ No newline at end of file diff --git a/templates/org/team/courseTeams.tmpl b/templates/org/team/courseTeams.tmpl index e7081b58fa..13557888c0 100644 --- a/templates/org/team/courseTeams.tmpl +++ b/templates/org/team/courseTeams.tmpl @@ -1,9 +1,17 @@ + {{template "base/head" .}}
{{template "org/header" .}} + {{template "org/navber_course" .}} +
{{template "base/alert" .}} - {{template "org/navber" .}} +
-- 2.34.1 From c4fe06151e7ea370c70fbb0c1f7e01b69f1dd049 Mon Sep 17 00:00:00 2001 From: zhoupzh Date: Wed, 19 Jan 2022 11:34:16 +0800 Subject: [PATCH 22/63] fix issue --- templates/explore/dataset_list.tmpl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/explore/dataset_list.tmpl b/templates/explore/dataset_list.tmpl index 7abc03363a..242f99dc90 100755 --- a/templates/explore/dataset_list.tmpl +++ b/templates/explore/dataset_list.tmpl @@ -26,7 +26,7 @@ +
\ No newline at end of file -- 2.34.1 From 588ac6edb551bc5ddecc8b9d6298050550d632d6 Mon Sep 17 00:00:00 2001 From: zhoupzh Date: Wed, 19 Jan 2022 11:38:31 +0800 Subject: [PATCH 23/63] fix issue --- options/locale/locale_en-US.ini | 1 + options/locale/locale_zh-CN.ini | 1 + 2 files changed, 2 insertions(+) diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 2902d603c7..3ca08ca4fc 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -51,6 +51,7 @@ organization = Organization mirror = Mirror new_repo = New Repository new_course=Publish Course +course_desc = Course Description new_migrate = New Migration new_dataset = New Dataset edit_dataset = Edit Dataset diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini index 934f6c9760..7b95d33ea8 100755 --- a/options/locale/locale_zh-CN.ini +++ b/options/locale/locale_zh-CN.ini @@ -51,6 +51,7 @@ organization=组织 mirror=镜像 new_repo=创建项目 new_course=发布课程 +course_desc=发布课程 new_dataset=创建数据集 new_migrate=迁移外部项目 edit_dataset = Edit Dataset -- 2.34.1 From 3d6ee0c573dd3aebef23a3e98e92e6d5e87f55e3 Mon Sep 17 00:00:00 2001 From: zhoupzh Date: Wed, 19 Jan 2022 11:39:53 +0800 Subject: [PATCH 24/63] fix issue --- options/locale/locale_zh-CN.ini | 2 +- templates/repo/createCourse.tmpl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini index 7b95d33ea8..94170cc9d7 100755 --- a/options/locale/locale_zh-CN.ini +++ b/options/locale/locale_zh-CN.ini @@ -51,7 +51,7 @@ organization=组织 mirror=镜像 new_repo=创建项目 new_course=发布课程 -course_desc=发布课程 +course_desc=课程描述 new_dataset=创建数据集 new_migrate=迁移外部项目 edit_dataset = Edit Dataset diff --git a/templates/repo/createCourse.tmpl b/templates/repo/createCourse.tmpl index d2a77eea9a..96266feed7 100644 --- a/templates/repo/createCourse.tmpl +++ b/templates/repo/createCourse.tmpl @@ -48,7 +48,7 @@
- +
-- 2.34.1 From df75bcc71c6f3e04a373d3350c4dad8fb02385fc Mon Sep 17 00:00:00 2001 From: ychao_1983 Date: Wed, 19 Jan 2022 11:50:44 +0800 Subject: [PATCH 25/63] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- routers/org/home.go | 1 + templates/org/course_list.tmpl | 7 +++---- templates/org/home_courses.tmpl | 4 ++++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/routers/org/home.go b/routers/org/home.go index 4eff151bfc..c9769f5596 100755 --- a/routers/org/home.go +++ b/routers/org/home.go @@ -158,6 +158,7 @@ func Home(ctx *context.Context) { for _, tag := range tags { for _, repo := range tag.RepoList { repo.GetCreator() + repo.GetOwner() } } diff --git a/templates/org/course_list.tmpl b/templates/org/course_list.tmpl index 1f43780364..6313ad0102 100644 --- a/templates/org/course_list.tmpl +++ b/templates/org/course_list.tmpl @@ -128,11 +128,10 @@
- - {{if .Creator}} - + {{if ne .CreatorID 0}} + {{else}} - + {{end}} {{$.i18n.Tr "org.repo_updated"}} :   {{TimeSinceUnixShort .UpdatedUnix}} diff --git a/templates/org/home_courses.tmpl b/templates/org/home_courses.tmpl index a06f06c208..70ea9b4211 100644 --- a/templates/org/home_courses.tmpl +++ b/templates/org/home_courses.tmpl @@ -208,7 +208,11 @@
{{.Alias}}

+ {{if ne .CreatorID 0}} 贡献者:{{.Creator.Name}} + {{else}} + 贡献者:{{.Owner.Name}} + {{end}}

-- 2.34.1 From 22bfbf350dfb245d3e969fb6cb430b2ca2adea40 Mon Sep 17 00:00:00 2001 From: zhoupzh Date: Wed, 19 Jan 2022 14:53:56 +0800 Subject: [PATCH 26/63] fix issue --- templates/repo/createCourse.tmpl | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/templates/repo/createCourse.tmpl b/templates/repo/createCourse.tmpl index 96266feed7..9417001d71 100644 --- a/templates/repo/createCourse.tmpl +++ b/templates/repo/createCourse.tmpl @@ -39,9 +39,9 @@
-