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:
Morlinest 2017-10-26 23:16:13 +02:00 committed by Lauris BH
parent 4d01ecaef3
commit ddb7f59ef4
16 changed files with 502 additions and 139 deletions

View file

@ -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.

View file

@ -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)

View file

@ -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)