diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index fbdc0ddec..f1bb453c7 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -666,12 +666,15 @@ func RegisterRoutes(m *macaron.Macaron) { //m.Get("/tag/*",context.RepoRefByType(context.RepoRefTag), viewfile.ViewFile) //m.Get("/commit/*", context.RepoRefByType(context.RepoRefCommit), viewfile.ViewFile) - - m.Get("", viewfile.RepoRefByType(context.RepoRefBranch), viewfile.ViewFile) + m.Get("/ext", viewfile.RepoRefByType(context.RepoRefBranch), viewfile.ViewFile) m.Get("/branch/*", viewfile.RepoRefByType(context.RepoRefBranch), viewfile.ViewFile) m.Get("/tag/*",viewfile.RepoRefByType(context.RepoRefTag), viewfile.ViewFile) m.Get("/commit/*", viewfile.RepoRefByType(context.RepoRefCommit), viewfile.ViewFile) + //update by 2021-01-12 end 引用自定义包; + + // alter on 2021/01/15 + m.Get("", viewfile.Readme) // reqRepoReader(models.UnitTypeCode), }) m.Combo("").Get(reqAnyRepoReader(), repo.Get). Delete(reqToken(), reqOwner(), repo.Delete). diff --git a/routers/api/v1/viewfile/viewfile.go b/routers/api/v1/viewfile/viewfile.go index 24beb539f..dc56b7038 100644 --- a/routers/api/v1/viewfile/viewfile.go +++ b/routers/api/v1/viewfile/viewfile.go @@ -2,6 +2,7 @@ package viewfile import ( "bytes" + "code.gitea.io/gitea/modules/log" "encoding/base64" "fmt" gotemplate "html/template" @@ -11,8 +12,7 @@ import ( "path" "strconv" "strings" - - "code.gitea.io/gitea/models" + "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/charset" @@ -23,6 +23,7 @@ import ( "code.gitea.io/gitea/modules/setting" "gitea.com/macaron/macaron" + ) func Map2DTO(ctx *context.APIContext) (dto *ReadmeDTO) { @@ -54,6 +55,7 @@ func RepoRefByType(refType context.RepoRefType) macaron.Handler { // For API calls. if ctx.Repo.GitRepo == nil { + fmt.Println("*******ctx.Repo.GitRepo is nil recreated") repoPath := models.RepoPath(ctx.Repo.Owner.Name, ctx.Repo.Repository.Name) ctx.Repo.GitRepo, err = git.OpenRepository(repoPath) if err != nil { @@ -214,20 +216,41 @@ func getRefNameFromPath(ctx *context.APIContext, path string, isExist func(strin return "" } +func GetRefType() macaron.Handler { + return func(ctx *context.APIContext) { + ref:=ctx.ParamsInt64(":ref") + fmt.Println("ref:",ref) + } +} //查询并加载readme接口内容; -func ViewFile(ctx *context.APIContext) { +func Readme(ctx *context.APIContext) { ctx.Data["Encoding"]="base64" + //refName := getRefName(ctx, context.RepoRefAny) + //fmt.Println("****************ctx.Repo.refName:",refName) - namedBlob,err:=getReadmeFileFromPath(ctx.Repo.Commit,ctx.Repo.TreePath) + //fmt.Println("****************ctx.Repo.TreePath:",ctx.Repo.TreePath) + treePath := ctx.Repo.TreePath + + ref:= ctx.QueryTrim("ref") + if ref == "" { + ref= ctx.Params(":ref") + if ref=="" { + ref = ctx.Repo.Repository.DefaultBranch + } + } + fmt.Println("***ref:",ref) + + namedBlob,err:=getReadmeFileFromPathExt(ctx,treePath,ref) if err !=nil || namedBlob==nil{ ctx.NotFound("getReadmeFileFromPath", err) return } + //fmt.Println("********getReadmeFileFromPathExt:",err," ",namedBlob) FoundFileItem:=namedBlob.name ctx.Repo.TreePath=FoundFileItem //找到指定文件; - fmt.Println("****getReadmeFileFromPath:",FoundFileItem) + //fmt.Println("**** reqRepoReader(models.UnitTypeCode):",FoundFileItem) ctx.Data["PageIsViewCode"] = true if ctx.Repo.Repository.IsEmpty { ctx.NotFound("Home", fmt.Errorf(ctx.Tr("Repository is empty"))) @@ -242,6 +265,93 @@ func ViewFile(ctx *context.APIContext) { ctx.Repo.RepoLink=`/`+ctx.Repo.Owner.Name+`/`+ctx.Repo.Repository.Name + ctx.Repo.IsViewCommit=true //此处无实际意义;加上为了编译 + + branchLink := ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL() + treeLink := branchLink + rawLink := ctx.Repo.RepoLink + "/raw/" + ctx.Repo.BranchNameSubURL() + //fmt.Println("******rawLink:",rawLink) + if len(ctx.Repo.TreePath) > 0 { + treeLink += "/" + ctx.Repo.TreePath + treeLink=strings.ReplaceAll(treeLink,"//","/") + } + + // Get current entry user currently looking at. + entry, err := ctx.Repo.Commit.GetTreeEntryByPath(ctx.Repo.TreePath) + //fmt.Println("*********GetTreeEntryByPath:",entry," ",err) + if err != nil { + ctx.NotFound("Repo.Commit.GetTreeEntryByPath", err) + return + } + if entry==nil { + ctx.NotFound("Repo.Commit.GetTreeEntryByPath", err) + return + } + renderFile(ctx, entry, treeLink, rawLink) + //if ctx.Written() { + // return + //} + + var treeNames []string + paths := make([]string, 0, 5) + if len(ctx.Repo.TreePath) > 0 { + treeNames = strings.Split(ctx.Repo.TreePath, "/") + fmt.Println("***treeNames:",treeNames) + for i := range treeNames { + paths = append(paths, strings.Join(treeNames[:i+1], "/")) + fmt.Println("***paths:",paths) + + } + ctx.Data["HasParentPath"] = true + if len(paths)-2 >= 0 { + ctx.Data["ParentPath"] = "/" + paths[len(paths)-2] + } + } + + + ctx.Data["Paths"] = paths + ctx.Data["TreeLink"] = treeLink + ctx.Data["TreeNames"] = treeNames + ctx.Data["BranchLink"] = branchLink + + fmt.Println("***rawLink:",rawLink) + fmt.Println("***paths:",paths) + fmt.Println("***treeLink:",treeLink) + fmt.Println("***treeNames:",treeNames) + fmt.Println("***branchLink:",branchLink) + + ctx.JSON(http.StatusOK, Map2DTO(ctx)) + +} + + +func ViewFile(ctx *context.APIContext) { + ctx.Data["Encoding"]="base64" + + fmt.Println("*********viewFile.ctx.Repo.TreePath:",ctx.Repo.TreePath) + namedBlob,err:=getReadmeFileFromPath(ctx.Repo.Commit,ctx.Repo.TreePath) + if err !=nil || namedBlob==nil{ + ctx.NotFound("getReadmeFileFromPath", err) + return + } + FoundFileItem:=namedBlob.name + ctx.Repo.TreePath=FoundFileItem //找到指定文件; + + fmt.Println("****getReadmeFileFromPath:",FoundFileItem) + ctx.Data["PageIsViewCode"] = true + if ctx.Repo.Repository.IsEmpty { + ctx.NotFound("Home", fmt.Errorf(ctx.Tr("Repository is empty"))) + return + } + + title := ctx.Repo.Repository.Owner.Name + "/" + ctx.Repo.Repository.Name + if len(ctx.Repo.Repository.Description) > 0 { + title += ": " + ctx.Repo.Repository.Description + } + ctx.Data["Title"] = title + + ctx.Repo.RepoLink=`/`+ctx.Repo.Owner.Name+`/`+ctx.Repo.Repository.Name + branchLink := ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL() //fmt.Println("******branchLink:",branchLink) treeLink := branchLink @@ -271,7 +381,7 @@ func ViewFile(ctx *context.APIContext) { ctx.NotFound("Repo.Commit.GetTreeEntryByPath", err) return } - renderFile(ctx, entry, treeLink, rawLink) + renderFile(ctx, entry, treeLink, rawLink) //if ctx.Written() { // return //} @@ -507,9 +617,9 @@ func linesBytesCount(s []byte) int { */ - // FIXME: There has to be a more efficient way of doing this func getReadmeFileFromPath(commit *git.Commit, treePath string) (*namedBlob, error) { + tree, err := commit.SubTree(treePath) if err != nil { return nil, err @@ -580,6 +690,107 @@ func getReadmeFileFromPath(commit *git.Commit, treePath string) (*namedBlob, err return readmeFile, nil } +// FIXME: There has to be a more efficient way of doing this +func getReadmeFileFromPathExt(ctx *context.APIContext, treePath, ref string) (*namedBlob, error) { + log.Info("*****************getReadmeFileFromPathExt.GetCommit:ref:%s treepath:%s", ref, treePath) + 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 nil,err + } + // We opened it, we should close it + 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 for the ref + commit, err := ctx.Repo.GitRepo.GetCommit(ref) + if err != nil { + return nil, err + } + //log.Info("********GetCommit:%v",commit) + + ctx.Repo.Commit=commit + + tree, err := commit.SubTree(treePath) + if err != nil { + return nil, err + } + //log.Info("********SubTree:%v",tree) + + entries, err := tree.ListEntries() + if err != nil { + return nil, err + } + //log.Info("********ListEntries:%v, %v",err,entries) + var readmeFiles [4]*namedBlob + var exts = []string{".md", ".txt", ""} // sorted by priority + for _, entry := range entries { + if entry.IsDir() { + continue + } + for i, ext := range exts { + if markup.IsReadmeFile(entry.Name(), ext) || IsReadmeFileExt(entry.Name(), ext) { + if readmeFiles[i] == nil || base.NaturalSortLess(readmeFiles[i].name, entry.Blob().Name()) { + name := entry.Name() + isSymlink := entry.IsLink() + target := entry + if isSymlink { + target, err = entry.FollowLinks() + if err != nil && !git.IsErrBadLink(err) { + return nil, err + } + } + if target != nil && (target.IsExecutable() || target.IsRegular()) { + readmeFiles[i] = &namedBlob{ + name, + isSymlink, + target.Blob(), + } + } + } + } + } + + if markup.IsReadmeFile(entry.Name()) { + if readmeFiles[3] == nil || base.NaturalSortLess(readmeFiles[3].name, entry.Blob().Name()) { + name := entry.Name() + isSymlink := entry.IsLink() + if isSymlink { + entry, err = entry.FollowLinks() + if err != nil && !git.IsErrBadLink(err) { + return nil, err + } + } + if entry != nil && (entry.IsExecutable() || entry.IsRegular()) { + readmeFiles[3] = &namedBlob{ + name, + isSymlink, + entry.Blob(), + } + } + } + } + } + + var readmeFile *namedBlob + for _, f := range readmeFiles { + if f != nil { + readmeFile = f + break + } + } + return readmeFile, nil +} + func IsReadmeFileExt(name string, ext ...string) bool { name = strings.ToLower(name) if len(ext) > 0 {