Add search mode option to /api/repo/search (#2756)
* Add repo type option to /api/repo/search * Add tests and fix result of collaborative filter in specific condition * Fix/optimize search & tests * Improve integration tests * Fix lint errors * Fix unit tests * Change and improve internal implementation of repo search * Use NonexistentID * Make search api more general * Change mirror and fork search behaviour * Fix tests & typo in comment
This commit is contained in:
parent
4d01ecaef3
commit
ddb7f59ef4
16 changed files with 502 additions and 139 deletions
|
@ -6,6 +6,7 @@ package repo
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
api "code.gitea.io/sdk/gitea"
|
||||
|
@ -15,9 +16,37 @@ import (
|
|||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
"code.gitea.io/gitea/routers/api/v1/convert"
|
||||
)
|
||||
|
||||
// SearchRepoOption options when searching repositories
|
||||
// swagger:parameters repoSearch
|
||||
type SearchRepoOption struct { // TODO: Move SearchRepoOption to Gitea SDK
|
||||
// Keyword to search
|
||||
//
|
||||
// in: query
|
||||
Keyword string `json:"q"`
|
||||
// Repository owner to search
|
||||
//
|
||||
// in: query
|
||||
OwnerID int64 `json:"uid"`
|
||||
// Limit of result
|
||||
//
|
||||
// maximum: setting.ExplorePagingNum
|
||||
// in: query
|
||||
PageSize int `json:"limit"`
|
||||
// Type of repository to search, related to owner
|
||||
//
|
||||
// in: query
|
||||
SearchMode string `json:"mode"`
|
||||
// Search only owners repositories
|
||||
// Has effect only if owner is provided and mode is not "collaborative"
|
||||
//
|
||||
// in: query
|
||||
OwnerExclusive bool `json:"exclusive"`
|
||||
}
|
||||
|
||||
// Search repositories via options
|
||||
func Search(ctx *context.APIContext) {
|
||||
// swagger:route GET /repos/search repository repoSearch
|
||||
|
@ -27,20 +56,44 @@ func Search(ctx *context.APIContext) {
|
|||
//
|
||||
// Responses:
|
||||
// 200: SearchResults
|
||||
// 422: validationError
|
||||
// 500: SearchError
|
||||
|
||||
opts := &models.SearchRepoOptions{
|
||||
Keyword: strings.Trim(ctx.Query("q"), " "),
|
||||
OwnerID: ctx.QueryInt64("uid"),
|
||||
PageSize: convert.ToCorrectPageSize(ctx.QueryInt("limit")),
|
||||
Keyword: strings.Trim(ctx.Query("q"), " "),
|
||||
OwnerID: ctx.QueryInt64("uid"),
|
||||
PageSize: convert.ToCorrectPageSize(ctx.QueryInt("limit")),
|
||||
Collaborate: util.OptionalBoolNone,
|
||||
}
|
||||
|
||||
if ctx.QueryBool("exclusive") {
|
||||
opts.Collaborate = util.OptionalBoolFalse
|
||||
}
|
||||
|
||||
var mode = ctx.Query("mode")
|
||||
switch mode {
|
||||
case "source":
|
||||
opts.Fork = util.OptionalBoolFalse
|
||||
opts.Mirror = util.OptionalBoolFalse
|
||||
case "fork":
|
||||
opts.Fork = util.OptionalBoolTrue
|
||||
case "mirror":
|
||||
opts.Mirror = util.OptionalBoolTrue
|
||||
case "collaborative":
|
||||
opts.Mirror = util.OptionalBoolFalse
|
||||
opts.Collaborate = util.OptionalBoolTrue
|
||||
case "":
|
||||
default:
|
||||
ctx.Error(http.StatusUnprocessableEntity, "", fmt.Errorf("Invalid search mode: \"%s\"", mode))
|
||||
return
|
||||
}
|
||||
|
||||
var err error
|
||||
if opts.OwnerID > 0 {
|
||||
var repoOwner *models.User
|
||||
if ctx.User != nil && ctx.User.ID == opts.OwnerID {
|
||||
repoOwner = ctx.User
|
||||
} else {
|
||||
var err error
|
||||
repoOwner, err = models.GetUserByID(opts.OwnerID)
|
||||
if err != nil {
|
||||
ctx.JSON(500, api.SearchError{
|
||||
|
@ -51,8 +104,8 @@ func Search(ctx *context.APIContext) {
|
|||
}
|
||||
}
|
||||
|
||||
if !repoOwner.IsOrganization() {
|
||||
opts.Collaborate = true
|
||||
if repoOwner.IsOrganization() {
|
||||
opts.Collaborate = util.OptionalBoolFalse
|
||||
}
|
||||
|
||||
// Check visibility.
|
||||
|
|
|
@ -108,14 +108,13 @@ func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) {
|
|||
keyword := strings.Trim(ctx.Query("q"), " ")
|
||||
|
||||
repos, count, err = models.SearchRepositoryByName(&models.SearchRepoOptions{
|
||||
Page: page,
|
||||
PageSize: opts.PageSize,
|
||||
OrderBy: orderBy,
|
||||
Private: opts.Private,
|
||||
Keyword: keyword,
|
||||
OwnerID: opts.OwnerID,
|
||||
Collaborate: true,
|
||||
AllPublic: true,
|
||||
Page: page,
|
||||
PageSize: opts.PageSize,
|
||||
OrderBy: orderBy,
|
||||
Private: opts.Private,
|
||||
Keyword: keyword,
|
||||
OwnerID: opts.OwnerID,
|
||||
AllPublic: true,
|
||||
})
|
||||
if err != nil {
|
||||
ctx.Handle(500, "SearchRepositoryByName", err)
|
||||
|
|
|
@ -15,6 +15,7 @@ import (
|
|||
"code.gitea.io/gitea/modules/base"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
"code.gitea.io/gitea/routers/repo"
|
||||
)
|
||||
|
||||
|
@ -157,13 +158,14 @@ func Profile(ctx *context.Context) {
|
|||
}
|
||||
} else {
|
||||
repos, count, err = models.SearchRepositoryByName(&models.SearchRepoOptions{
|
||||
Keyword: keyword,
|
||||
OwnerID: ctxUser.ID,
|
||||
OrderBy: orderBy,
|
||||
Private: showPrivate,
|
||||
Page: page,
|
||||
PageSize: setting.UI.User.RepoPagingNum,
|
||||
Starred: true,
|
||||
Keyword: keyword,
|
||||
OwnerID: ctxUser.ID,
|
||||
OrderBy: orderBy,
|
||||
Private: showPrivate,
|
||||
Page: page,
|
||||
PageSize: setting.UI.User.RepoPagingNum,
|
||||
Starred: true,
|
||||
Collaborate: util.OptionalBoolFalse,
|
||||
})
|
||||
if err != nil {
|
||||
ctx.Handle(500, "SearchRepositoryByName", err)
|
||||
|
@ -199,14 +201,13 @@ func Profile(ctx *context.Context) {
|
|||
ctx.Data["Total"] = total
|
||||
} else {
|
||||
repos, count, err = models.SearchRepositoryByName(&models.SearchRepoOptions{
|
||||
Keyword: keyword,
|
||||
OwnerID: ctxUser.ID,
|
||||
OrderBy: orderBy,
|
||||
Private: showPrivate,
|
||||
Page: page,
|
||||
IsProfile: true,
|
||||
PageSize: setting.UI.User.RepoPagingNum,
|
||||
Collaborate: true,
|
||||
Keyword: keyword,
|
||||
OwnerID: ctxUser.ID,
|
||||
OrderBy: orderBy,
|
||||
Private: showPrivate,
|
||||
Page: page,
|
||||
IsProfile: true,
|
||||
PageSize: setting.UI.User.RepoPagingNum,
|
||||
})
|
||||
if err != nil {
|
||||
ctx.Handle(500, "SearchRepositoryByName", err)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue