335 lines
8.6 KiB
Go
335 lines
8.6 KiB
Go
package viewfile
|
||
|
||
import (
|
||
"fmt"
|
||
"net/http"
|
||
"net/url"
|
||
"path/filepath"
|
||
"strings"
|
||
|
||
"code.gitea.io/gitea/models"
|
||
"code.gitea.io/gitea/modules/context"
|
||
"code.gitea.io/gitea/modules/git"
|
||
"code.gitea.io/gitea/modules/repofiles"
|
||
repo_module "code.gitea.io/gitea/modules/repository"
|
||
)
|
||
|
||
func FindFiles(ctx *context.APIContext) {
|
||
// swagger:operation GET /repos/{owner}/{repo}/find repository find
|
||
// ---
|
||
// summary: The search file contains subdirectories, which is a custom interface *****
|
||
// produces:
|
||
// - application/json
|
||
// parameters:
|
||
// - name: owner
|
||
// in: path
|
||
// description: owner of the repo
|
||
// type: string
|
||
// required: true
|
||
// - name: repo
|
||
// in: path
|
||
// description: name of the repo
|
||
// type: string
|
||
// required: true
|
||
// - name: ref
|
||
// in: query
|
||
// description: "The name of the commit/branch/tag. Default the repository’s default branch (usually master)"
|
||
// type: string
|
||
// required: false
|
||
// - name: q
|
||
// in: query
|
||
// description: "Search keywords"
|
||
// type: string
|
||
// required: false
|
||
// responses:
|
||
// "200":
|
||
// "$ref": "#/responses/SearchFileItemList"
|
||
// "404":
|
||
// "$ref": "#/responses/notFound"
|
||
|
||
treePath := ctx.Repo.TreePath
|
||
|
||
ref := ctx.Query("ref")
|
||
if ref == "" {
|
||
ref = ctx.Repo.Repository.DefaultBranch
|
||
}
|
||
|
||
keyWords := ctx.Query("q")
|
||
if keyWords == "" {
|
||
|
||
}
|
||
fileList, err := FindFileFromPathEtx(ctx, treePath, ref, keyWords)
|
||
if err != nil {
|
||
ctx.ServerError("FindFileFromPathEtx", 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 FindFileFromPathEtx(ctx *context.APIContext, treePath, ref, key string) (fileList []*SearchFileItem, err error) {
|
||
if ctx.Repo.GitRepo == nil {
|
||
repoPath := models.RepoPath(ctx.Repo.Owner.Name, ctx.Repo.Repository.Name)
|
||
ctx.Repo.GitRepo, err = git.OpenRepository(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.ListEntriesRecursive()
|
||
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 = string(repofiles.ContentTypeRegular)
|
||
} else if entry.IsDir() {
|
||
item.Type = string(repofiles.ContentTypeDir)
|
||
} else if entry.IsLink() {
|
||
item.Type = string(repofiles.ContentTypeLink)
|
||
} else if entry.IsSubModule() {
|
||
item.Type = string(repofiles.ContentTypeSubmodule)
|
||
}
|
||
fileList = append(fileList, item)
|
||
|
||
}
|
||
}
|
||
return
|
||
|
||
}
|
||
|
||
func LatestRelease(ctx *context.APIContext) {
|
||
// swagger:operation GET /repos/{owner}/{repo}/releases/latest repository latest
|
||
// ---
|
||
// summary: Get the last updated Release version of the repository., which is a custom interface ****
|
||
// produces:
|
||
// - application/json
|
||
// parameters:
|
||
// - name: owner
|
||
// in: path
|
||
// description: owner of the repo
|
||
// type: string
|
||
// required: true
|
||
// - name: repo
|
||
// in: path
|
||
// description: name of the repo
|
||
// type: string
|
||
// required: true
|
||
// responses:
|
||
// "200":
|
||
// "$ref": "#/responses/release"
|
||
// "404":
|
||
// "$ref": "#/responses/notFound"
|
||
|
||
var err error
|
||
if ctx.Repo.GitRepo == nil {
|
||
repoPath := models.RepoPath(ctx.Repo.Owner.Name, ctx.Repo.Repository.Name)
|
||
ctx.Repo.GitRepo, err = git.OpenRepository(repoPath)
|
||
if err != nil {
|
||
ctx.ServerError("Reporef Invalid repo"+repoPath, err)
|
||
return
|
||
}
|
||
defer func() {
|
||
if ctx.Repo.GitRepo != nil {
|
||
ctx.Repo.GitRepo.Close()
|
||
}
|
||
}()
|
||
}
|
||
release, err := models.GetLatestReleaseByRepoIDExt(ctx.Repo.Repository.ID)
|
||
fmt.Println("****************ctx.Repo.Repository.ID:", ctx.Repo.Repository.ID, " ", release, " ", err)
|
||
|
||
if err != nil {
|
||
if models.IsErrReleaseNotExist(err) {
|
||
ctx.NotFound("LatestRelease", err)
|
||
return
|
||
}
|
||
ctx.ServerError("GetLatestReleaseByRepoIDExt", err)
|
||
return
|
||
|
||
}
|
||
if err := release.LoadAttributes(); err != nil {
|
||
ctx.ServerError("LoadAttributes", err)
|
||
return
|
||
}
|
||
release.Publisher.Passwd = ""
|
||
ctx.JSON(http.StatusOK, release)
|
||
|
||
}
|
||
|
||
type CountDTO struct {
|
||
Branch struct {
|
||
CommitCount int64 `json:"commit_count"`
|
||
BranchName string `json:"branch_name"`
|
||
} `json:"branch"`
|
||
ReleaseCount int64 `json:"release_count"`
|
||
TagCount int64 `json:"tag_count"`
|
||
BranchCount int64 `json:"branch_count"`
|
||
}
|
||
|
||
func GetCommitCount(ctx *context.APIContext) {
|
||
// swagger:operation GET /repos/{owner}/{repo}/count repository Count
|
||
// ---
|
||
// summary: Get commit quantity by branch which is a custom interface ****
|
||
// produces:
|
||
// - application/json
|
||
// parameters:
|
||
// - name: owner
|
||
// in: path
|
||
// description: owner of the repo
|
||
// type: string
|
||
// required: true
|
||
// - name: repo
|
||
// in: path
|
||
// description: name of the repo
|
||
// type: string
|
||
// required: true
|
||
// - name: ref
|
||
// in: query
|
||
// description: "The name of the commit/branch/tag. Default the repository’s default branch (usually master)"
|
||
// type: string
|
||
// required: false
|
||
// responses:
|
||
// "200":
|
||
// "$ref": "#/responses/CountDTO"
|
||
// "404":
|
||
// "$ref": "#/responses/notFound"
|
||
|
||
ref := ctx.QueryTrim("ref") // determine whether the ref empty
|
||
if ref == "" {
|
||
ref = ctx.Params(":ref")
|
||
if ref == "" {
|
||
ref = ctx.Repo.Repository.DefaultBranch
|
||
}
|
||
}
|
||
var err error
|
||
if ctx.Repo.GitRepo == nil {
|
||
|
||
repoPath := models.RepoPath(ctx.Repo.Owner.Name, ctx.Repo.Repository.Name)
|
||
ctx.Repo.GitRepo, err = git.OpenRepository(repoPath)
|
||
if err != nil {
|
||
ctx.Error(http.StatusInternalServerError, "RepoRef Invalid repo"+repoPath, err)
|
||
return
|
||
|
||
}
|
||
defer func() {
|
||
|
||
// If it's been set to nil then assume someone else has closed it
|
||
if ctx.Repo.GitRepo != nil {
|
||
ctx.Repo.GitRepo.Close()
|
||
}
|
||
}()
|
||
}
|
||
//Get the commit object of the ref
|
||
commit, err2 := ctx.Repo.GitRepo.GetCommit(ref)
|
||
if err2 != nil {
|
||
ctx.Error(http.StatusInternalServerError, "ctx.Repo.GitRepo.GetCommit", err)
|
||
return
|
||
}
|
||
|
||
ctx.Repo.Commit = commit
|
||
// Get the count of the commit
|
||
CommitCount, err := ctx.Repo.Commit.CommitsCount()
|
||
if err != nil {
|
||
ctx.Error(http.StatusInternalServerError, "Get the CommitsCount", err)
|
||
return
|
||
}
|
||
|
||
opts := models.FindReleasesOptions{
|
||
ListOptions: models.ListOptions{
|
||
Page: 1,
|
||
PageSize: 1000,
|
||
},
|
||
|
||
IncludeDrafts: true,
|
||
IncludeTags: true,
|
||
}
|
||
// Get the release object of the ref
|
||
ReleaseCount, err3 := models.GetReleaseCountByRepoID(ctx.Repo.Repository.ID, opts)
|
||
if err3 != nil {
|
||
ctx.Error(http.StatusInternalServerError, "GetReleaseCountByRepoId", err)
|
||
return
|
||
}
|
||
|
||
branches, _, err := repo_module.GetBranchesNoLimit(ctx.Repo.Repository)
|
||
if err != nil {
|
||
ctx.Error(http.StatusInternalServerError, "GetBranches", err)
|
||
return
|
||
}
|
||
// Get the tag object
|
||
Tags, err4 := ctx.Repo.GitRepo.GetTags()
|
||
if err4 != nil {
|
||
ctx.Error(http.StatusInternalServerError, "GetTags", err)
|
||
return
|
||
}
|
||
countDTO := &CountDTO{}
|
||
countDTO.Branch.CommitCount = CommitCount
|
||
countDTO.Branch.BranchName = ref
|
||
countDTO.BranchCount = int64(len(branches))
|
||
countDTO.TagCount = int64(len(Tags))
|
||
countDTO.ReleaseCount = ReleaseCount
|
||
ctx.JSON(http.StatusOK, countDTO)
|
||
}
|