新增:搜索文件接口

This commit is contained in:
yystopf 2023-01-04 17:52:48 +08:00
parent 53a2245a73
commit 0883f29c1c
2 changed files with 116 additions and 0 deletions

View File

@ -132,6 +132,7 @@ func Routers(ctx gocontext.Context) *web.Route {
m.Post("", bind(hat_api.BatchChangeFileOptions{}), repo.BatchChangeFile)
}, reqRepoWriter(unit.TypeCode), reqToken())
}, reqRepoReader(unit.TypeCode))
m.Get("/find", reqRepoReader(unit.TypeCode), repo.FindFiles)
m.Group("/git", func() {
m.Group("/commits", func() {
m.Get("/{sha}", repo.GetSingleCommit)

View File

@ -4,6 +4,8 @@ import (
"encoding/base64"
"fmt"
"net/http"
"net/url"
"path/filepath"
"strings"
"time"
@ -246,3 +248,116 @@ func GetContents(ctx *context.APIContext) {
func GetContentsList(ctx *context.APIContext) {
GetContents(ctx)
}
func FindFiles(ctx *context.APIContext) {
treePath := ctx.Repo.TreePath
ref := ctx.FormString("ref")
if ref == "" {
ref = ctx.Repo.Repository.DefaultBranch
}
keyWords := ctx.FormString("q")
var fileList []*SearchFileItem
var err error
if keyWords != "" {
fileList, err = FindFileFromPath(ctx, treePath, ref, keyWords)
if err != nil {
ctx.Error(http.StatusInternalServerError, "FindFileFromPath", err)
return
}
}
ctx.JSON(http.StatusOK, fileList)
}
type SearchFileItem struct {
Name string `json:"name"`
Path string `json:"path"`
SHA string `json:"sha"`
Type string `json:"type"`
Size int64 `json:"size"`
URL *string `json:"url"`
HTMLURL *string `json:"html_url"`
}
func FindFileFromPath(ctx *context.APIContext, treePath, ref, key string) (fileList []*SearchFileItem, err error) {
if ctx.Repo.GitRepo == nil {
ctx.Repo.GitRepo, err = git.OpenRepository(ctx, ctx.Repo.Repository.RepoPath())
if err != nil {
ctx.ServerError("OpenRepository", err)
return nil, err
}
defer func() {
if ctx.Repo.GitRepo != nil {
ctx.Repo.GitRepo.Close()
}
}()
}
// get the commit object for the ref
commit, err := ctx.Repo.GitRepo.GetCommit(ref)
if err != nil {
ctx.ServerError("GetCommit", err)
return nil, err
}
tree, err2 := commit.SubTree(treePath)
if err2 != nil {
ctx.ServerError("SubTree", err)
return nil, err2
}
entries, err3 := tree.ListEntriesRecursiveFast()
if err3 != nil {
ctx.ServerError("ListEntries", err3)
return nil, err3
}
fileList = make([]*SearchFileItem, 0, 0)
for _, entry := range entries {
if entry.IsDir() {
continue
}
filename := filepath.Base(entry.Name())
if strings.Contains(strings.ToLower(filename), strings.ToLower(key)) || key == "" {
name := entry.Name()
treePath = name
selfURL, err := url.Parse(fmt.Sprintf("%s/contents/%s?ref=%s", ctx.Repo.Repository.APIURL(), treePath, ref))
if err != nil {
return nil, err
}
selfURLString := selfURL.String()
refType := ctx.Repo.GitRepo.GetRefType(ref)
if refType == "invalid" {
return nil, fmt.Errorf("no commit found for the ref [ref: %s]", ref)
}
htmlURL, err := url.Parse(fmt.Sprintf("%s/src/%s/%s/%s", ctx.Repo.Repository.HTMLURL(), refType, ref, treePath))
if err != nil {
return nil, err
}
htmlURLString := htmlURL.String()
item := &SearchFileItem{
Name: filename,
Path: treePath,
SHA: entry.ID.String(),
Type: entry.Type(),
Size: entry.Size(),
URL: &selfURLString,
HTMLURL: &htmlURLString,
}
// Now populate the rest of the ContentsResponse based on entry type
if entry.IsRegular() || entry.IsExecutable() {
item.Type = "file"
} else if entry.IsDir() {
item.Type = "dir"
} else if entry.IsLink() {
item.Type = "symlink"
} else if entry.IsSubModule() {
item.Type = "submodule"
}
fileList = append(fileList, item)
}
}
return
}