新增:代码搜索接口

This commit is contained in:
yystopf 2025-07-24 08:30:51 +08:00
parent c954b4799e
commit dfe0ce8de0
2 changed files with 123 additions and 0 deletions

View File

@ -30,6 +30,7 @@ import (
"code.gitlink.org.cn/Gitlink/gitea_hat.git/routers/hat/org"
"code.gitlink.org.cn/Gitlink/gitea_hat.git/routers/hat/repo"
"code.gitlink.org.cn/Gitlink/gitea_hat.git/routers/hat/repo/actions"
"code.gitlink.org.cn/Gitlink/gitea_hat.git/routers/hat/repo/explore"
"code.gitlink.org.cn/Gitlink/gitea_hat.git/routers/hat/user"
"github.com/go-chi/cors"
)
@ -125,6 +126,9 @@ func Routers() *web.Route {
m.Post("/update_hook_arm", bind(gitea_api.RepositoryPayload{}), repo.UpdateHookArm)
m.Post("/update_repo_size_limit_hook", bind(gitea_api.RepositoryPayload{}), repo.UpdateRepoSizeLimitHook)
m.Group("/repos", func() {
if setting.Indexer.RepoIndexerEnabled {
m.Get("/explore/code", explore.Code)
}
m.Group("/{username}/{reponame}", func() {
m.Combo("").Delete(reqToken(), reqOwner(), repo.Delete)
m.Group("/actions", func() {

View File

@ -0,0 +1,119 @@
package explore
import (
"fmt"
"math"
"net/http"
"strconv"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/context"
code_indexer "code.gitea.io/gitea/modules/indexer/code"
"code.gitea.io/gitea/modules/setting"
)
func Code(ctx *context.APIContext) {
language := ctx.FormString("language")
keyword := ctx.FormString("keyword")
queryType := ctx.FormString("query_type")
isMatch := queryType == "match"
page := ctx.FormInt("page")
if page <= 0 {
page = 1
}
var (
repoIDs []int64
err error
isAdmin bool
)
if ctx.Doer != nil {
isAdmin = ctx.Doer.IsAdmin
}
if ctx.Doer == nil || !isAdmin {
repoIDs, err = repo_model.FindUserCodeAccessibleRepoIDs(ctx, ctx.Doer)
if err != nil {
ctx.Error(http.StatusInternalServerError, "FindUserCodeAccessibleRepoIDs", err)
return
}
}
var (
total int
searchResults []*code_indexer.Result
searchResultLanguages []*code_indexer.SearchResultLanguages
)
var codeIndexerUnavailable bool
var repoMaps map[int64]*repo_model.Repository
if (len(repoIDs) > 0) || isAdmin {
total, searchResults, searchResultLanguages, err = code_indexer.PerformSearch(ctx, repoIDs, language, keyword, page, setting.UI.RepoSearchPagingNum, isMatch)
if err != nil {
if code_indexer.IsAvailable(ctx) {
ctx.Error(http.StatusInternalServerError, "SearchResults", err)
return
}
codeIndexerUnavailable = true
} else {
codeIndexerUnavailable = !code_indexer.IsAvailable(ctx)
}
loadRepoIDs := make([]int64, 0, len(searchResults))
for _, result := range searchResults {
var find bool
for _, id := range loadRepoIDs {
if id == result.RepoID {
find = true
break
}
}
if !find {
loadRepoIDs = append(loadRepoIDs, result.RepoID)
}
}
repoMaps, err := repo_model.GetRepositoriesMapByIDs(loadRepoIDs)
if err != nil {
ctx.Error(http.StatusInternalServerError, "GetRepositoriesMapByIDs", err)
return
}
repoMaps = repoMaps
if len(loadRepoIDs) != len(repoMaps) {
// Remove deleted repos from search results
cleanedSearchResults := make([]*code_indexer.Result, 0, len(repoMaps))
for _, sr := range searchResults {
if _, found := repoMaps[sr.RepoID]; found {
cleanedSearchResults = append(cleanedSearchResults, sr)
}
}
searchResults = cleanedSearchResults
}
}
pageCount := int(math.Ceil(float64(total) / float64(setting.UI.RepoSearchPagingNum)))
ctx.Resp.Header().Set("X-Page", strconv.Itoa(page))
ctx.Resp.Header().Set("X-PerPage", strconv.Itoa(setting.UI.RepoSearchPagingNum))
ctx.Resp.Header().Set("X-Total", strconv.FormatInt(int64(total), 10))
ctx.Resp.Header().Set("X-PageCount", strconv.Itoa(pageCount))
ctx.Resp.Header().Set("X-HasMore", strconv.FormatBool(page < pageCount))
ctx.SetLinkHeader(int(total), setting.UI.RepoSearchPagingNum)
ctx.Resp.Header().Set("X-Total-Count", fmt.Sprintf("%d", total))
ctx.JSON(http.StatusOK, struct {
CodeIndexerUnavailable bool
RepoMaps map[int64]*repo_model.Repository
SearchResults []*code_indexer.Result
SearchResultLanguages []*code_indexer.SearchResultLanguages
}{
CodeIndexerUnavailable: codeIndexerUnavailable,
RepoMaps: repoMaps,
SearchResults: searchResults,
SearchResultLanguages: searchResultLanguages,
})
}