mirror of
				https://github.com/go-gitea/gitea
				synced 2025-10-31 11:28:24 +00:00 
			
		
		
		
	API: Return primary language and repository language stats API URL (#18396)
This commit is contained in:
		| @@ -222,6 +222,30 @@ func (repo *Repository) MustOwner() *user_model.User { | |||||||
| 	return repo.mustOwner(db.DefaultContext) | 	return repo.mustOwner(db.DefaultContext) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // LoadAttributes loads attributes of the repository. | ||||||
|  | func (repo *Repository) LoadAttributes(ctx context.Context) error { | ||||||
|  | 	// Load owner | ||||||
|  | 	if err := repo.GetOwner(ctx); err != nil { | ||||||
|  | 		return fmt.Errorf("load owner: %w", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Load primary language | ||||||
|  | 	stats := make(LanguageStatList, 0, 1) | ||||||
|  | 	if err := db.GetEngine(ctx). | ||||||
|  | 		Where("`repo_id` = ? AND `is_primary` = ? AND `language` != ?", repo.ID, true, "other"). | ||||||
|  | 		Find(&stats); err != nil { | ||||||
|  | 		return fmt.Errorf("find primary languages: %w", err) | ||||||
|  | 	} | ||||||
|  | 	stats.LoadAttributes() | ||||||
|  | 	for _, st := range stats { | ||||||
|  | 		if st.RepoID == repo.ID { | ||||||
|  | 			repo.PrimaryLanguage = st | ||||||
|  | 			break | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
| // FullName returns the repository full name | // FullName returns the repository full name | ||||||
| func (repo *Repository) FullName() string { | func (repo *Repository) FullName() string { | ||||||
| 	return repo.OwnerName + "/" + repo.Name | 	return repo.OwnerName + "/" + repo.Name | ||||||
|   | |||||||
| @@ -623,7 +623,7 @@ func FindUserAccessibleRepoIDs(user *user_model.User) ([]int64, error) { | |||||||
| } | } | ||||||
|  |  | ||||||
| // GetUserRepositories returns a list of repositories of given user. | // GetUserRepositories returns a list of repositories of given user. | ||||||
| func GetUserRepositories(opts *SearchRepoOptions) ([]*repo_model.Repository, int64, error) { | func GetUserRepositories(opts *SearchRepoOptions) (RepositoryList, int64, error) { | ||||||
| 	if len(opts.OrderBy) == 0 { | 	if len(opts.OrderBy) == 0 { | ||||||
| 		opts.OrderBy = "updated_unix DESC" | 		opts.OrderBy = "updated_unix DESC" | ||||||
| 	} | 	} | ||||||
| @@ -646,6 +646,6 @@ func GetUserRepositories(opts *SearchRepoOptions) ([]*repo_model.Repository, int | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	sess = sess.Where(cond).OrderBy(opts.OrderBy.String()) | 	sess = sess.Where(cond).OrderBy(opts.OrderBy.String()) | ||||||
| 	repos := make([]*repo_model.Repository, 0, opts.PageSize) | 	repos := make(RepositoryList, 0, opts.PageSize) | ||||||
| 	return repos, count, db.SetSessionPagination(sess, opts).Find(&repos) | 	return repos, count, db.SetSessionPagination(sess, opts).Find(&repos) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -125,6 +125,13 @@ func innerToRepo(repo *repo_model.Repository, mode perm.AccessMode, isParent boo | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	var language string | ||||||
|  | 	if repo.PrimaryLanguage != nil { | ||||||
|  | 		language = repo.PrimaryLanguage.Language | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	repoAPIURL := repo.APIURL() | ||||||
|  |  | ||||||
| 	return &api.Repository{ | 	return &api.Repository{ | ||||||
| 		ID:                        repo.ID, | 		ID:                        repo.ID, | ||||||
| 		Owner:                     ToUserWithAccessMode(repo.Owner, mode), | 		Owner:                     ToUserWithAccessMode(repo.Owner, mode), | ||||||
| @@ -144,6 +151,8 @@ func innerToRepo(repo *repo_model.Repository, mode perm.AccessMode, isParent boo | |||||||
| 		CloneURL:                  cloneLink.HTTPS, | 		CloneURL:                  cloneLink.HTTPS, | ||||||
| 		OriginalURL:               repo.SanitizedOriginalURL(), | 		OriginalURL:               repo.SanitizedOriginalURL(), | ||||||
| 		Website:                   repo.Website, | 		Website:                   repo.Website, | ||||||
|  | 		Language:                  language, | ||||||
|  | 		LanguagesURL:              repoAPIURL + "/languages", | ||||||
| 		Stars:                     repo.NumStars, | 		Stars:                     repo.NumStars, | ||||||
| 		Forks:                     repo.NumForks, | 		Forks:                     repo.NumForks, | ||||||
| 		Watchers:                  repo.NumWatches, | 		Watchers:                  repo.NumWatches, | ||||||
|   | |||||||
| @@ -59,6 +59,8 @@ type Repository struct { | |||||||
| 	Parent        *Repository `json:"parent"` | 	Parent        *Repository `json:"parent"` | ||||||
| 	Mirror        bool        `json:"mirror"` | 	Mirror        bool        `json:"mirror"` | ||||||
| 	Size          int         `json:"size"` | 	Size          int         `json:"size"` | ||||||
|  | 	Language      string      `json:"language"` | ||||||
|  | 	LanguagesURL  string      `json:"languages_url"` | ||||||
| 	HTMLURL       string      `json:"html_url"` | 	HTMLURL       string      `json:"html_url"` | ||||||
| 	SSHURL        string      `json:"ssh_url"` | 	SSHURL        string      `json:"ssh_url"` | ||||||
| 	CloneURL      string      `json:"clone_url"` | 	CloneURL      string      `json:"clone_url"` | ||||||
|   | |||||||
| @@ -533,6 +533,11 @@ func Get(ctx *context.APIContext) { | |||||||
| 	//   "200": | 	//   "200": | ||||||
| 	//     "$ref": "#/responses/Repository" | 	//     "$ref": "#/responses/Repository" | ||||||
|  |  | ||||||
|  | 	if err := ctx.Repo.Repository.LoadAttributes(ctx); err != nil { | ||||||
|  | 		ctx.Error(http.StatusInternalServerError, "Repository.LoadAttributes", err) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	ctx.JSON(http.StatusOK, convert.ToRepo(ctx.Repo.Repository, ctx.Repo.AccessMode)) | 	ctx.JSON(http.StatusOK, convert.ToRepo(ctx.Repo.Repository, ctx.Repo.AccessMode)) | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -32,6 +32,11 @@ func listUserRepos(ctx *context.APIContext, u *user_model.User, private bool) { | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if err := repos.LoadAttributes(); err != nil { | ||||||
|  | 		ctx.Error(http.StatusInternalServerError, "RepositoryList.LoadAttributes", err) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	apiRepos := make([]*api.Repository, 0, len(repos)) | 	apiRepos := make([]*api.Repository, 0, len(repos)) | ||||||
| 	for i := range repos { | 	for i := range repos { | ||||||
| 		access, err := models.AccessLevel(ctx.User, repos[i]) | 		access, err := models.AccessLevel(ctx.User, repos[i]) | ||||||
|   | |||||||
| @@ -17188,6 +17188,14 @@ | |||||||
|         "internal_tracker": { |         "internal_tracker": { | ||||||
|           "$ref": "#/definitions/InternalTracker" |           "$ref": "#/definitions/InternalTracker" | ||||||
|         }, |         }, | ||||||
|  |         "language": { | ||||||
|  |           "type": "string", | ||||||
|  |           "x-go-name": "Language" | ||||||
|  |         }, | ||||||
|  |         "languages_url": { | ||||||
|  |           "type": "string", | ||||||
|  |           "x-go-name": "LanguagesURL" | ||||||
|  |         }, | ||||||
|         "mirror": { |         "mirror": { | ||||||
|           "type": "boolean", |           "type": "boolean", | ||||||
|           "x-go-name": "Mirror" |           "x-go-name": "Mirror" | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user