add wiki.go content.go fix, api.go repo.go

This commit is contained in:
wonderful 2021-08-05 16:35:04 +08:00
parent ac62431593
commit dbd0b2661e
4 changed files with 590 additions and 6 deletions

View File

@ -2132,7 +2132,7 @@ func (repo *Repository) GetWikis(listOptions ListOptions) ([]*Repository, error)
return wikis, x.Find(&wikis, &Repository{WikiID: repo.ID})
}
sess := listOptions.getPaginatedSession()
sess := listOptions.GetPaginatedSession()
wikis := make([]*Repository, 0, listOptions.PageSize)
return wikis, sess.Find(&wikis, &Repository{WikiID: repo.ID})
}
@ -2145,7 +2145,7 @@ func (repo *Repository) GetForks(listOptions ListOptions) ([]*Repository, error)
return forks, x.Find(&forks, &Repository{ForkID: repo.ID})
}
sess := listOptions.getPaginatedSession()
sess := listOptions.GetPaginatedSession()
forks := make([]*Repository, 0, listOptions.PageSize)
return forks, sess.Find(&forks, &Repository{ForkID: repo.ID})
}

309
modules/wikis/content.go Normal file
View File

@ -0,0 +1,309 @@
package wikis
import (
//"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/git"
wiki_service "code.gitea.io/gitea/services/wiki"
"io/ioutil"
"net/url"
)
//type ContentType string
//const (
// // ContentTypeRegular regular content type (file)
// ContentTypeRegular ContentType = "file"
// // ContentTypeDir dir content type (dir)
// ContentTypeDir ContentType = "dir"
// // ContentLink link content type (symlink)
// ContentTypeLink ContentType = "symlink"
// // ContentTag submodule content type (submodule)
// ContentTypeSubmodule ContentType = "submodule"
//)
//
//func GetContentsOrList(repo *models.Repository, treePath, ref string) (interface{}, error) {
// startTotal := time.Now()
// log.Info("Enter time:%v", startTotal.Format("2006-01-02 15:04:05.000"))
// defer func() {
// log.Info("***GetContentsOrList耗时:%v", time.Now().Sub(startTotal))
// }()
// start := time.Now()
// if repo.IsEmpty {
// return make([]interface{}, 0), nil
// }
// if ref == "" {
// ref = repo.DefaultBranch
// }
// origRef := ref
//
// start = time.Now()
// // Check that the path given in opts.treePath is valid (not a git path)
// cleanTreePath := repofiles.CleanUploadFileName(treePath)
// if cleanTreePath == "" && treePath != "" {
// return nil, models.ErrFilenameInvalid{
// Path: treePath,
// }
// }
// log.Info("*****************GetContentsOrList.CleanUploadFileName:%v", time.Now().Sub(start))
// start = time.Now()
// treePath = cleanTreePath
// gitRepo, err := git.OpenRepository(repo.RepoPath())
// if err != nil {
// return nil, err
// }
// defer gitRepo.Close()
// log.Info("*****************GetContentsOrList.OpenRepository:%v", time.Now().Sub(start))
// start = time.Now()
// // Get the commit object for the ref
// commit, err := gitRepo.GetCommit(ref)
// if err != nil {
// return nil, err
// }
// log.Info("*****************GetContentsOrList.GetCommit:ret:%s treepath:%s", ref, treePath)
// log.Info("*****************GetContentsOrList.GetCommit:%v", time.Now().Sub(start), " ref:", ref, " treePath:", treePath)
// start = time.Now()
// entry, err := commit.GetTreeEntryByPath(treePath)
// if err != nil {
// return nil, err
// }
// log.Info("*****************GetContentsOrList.GetTreeEntryByPath:%v", time.Now().Sub(start))
// if entry.Type() != "tree" {
// a, b := repofiles.GetContents(repo, treePath, origRef, false)
// log.Info("*****************GetContentsOrList.GetContents***:%v", time.Now().Sub(start))
// return a, b
// }
//
// // We are in a directory, so we return a list of FileContentResponse objects
// var fileList []*api.Wiki
// start = time.Now()
// gitTree, err := commit.SubTree(treePath)
// if err != nil {
// return nil, err
// }
// log.Info("*****************GetContentsOrList.SubTree:%v", time.Now().Sub(start))
// entries, err := gitTree.ListEntries()
// if err != nil {
// return nil, err
// }
// start = time.Now()
// //add by qiubing
// commitsInfo, _, err := entries.GetCommitsInfo(commit, treePath, nil)
// if err != nil {
// return nil, err
// }
// //end by qiubing
// start1 := time.Now()
// log.Info("****GetContentsOrList.GetCommitsInfo:%v", time.Now().Sub(start))
// for _, e := range entries {
// subTreePath := path.Join(treePath, e.Name())
// start2 := time.Now()
// fileContentResponse, err := GetContentsExt(gitRepo, commit, repo, subTreePath, origRef, true)
// log.Info("*****GetContentsOrList.GetContents:%s %v", e.Name(), time.Now().Sub(start2))
// // add by qiubing
// for _, commitInfo := range commitsInfo {
// if treeEntry, ok := commitInfo[0].(*git.TreeEntry); ok {
// if treeEntry.Name() == fileContentResponse.Name {
// var entryCommit *git.Commit
// if value, ok := commitInfo[1].(*git.Commit); ok {
// entryCommit = value
// } else if value, ok := commitInfo[1].(*git.SubModuleFile); ok {
// entryCommit = value.Commit
// }
// fileContentResponse.LatestCommit = api.ContentsResponseCommi{
// Message: entryCommit.CommitMessage,
// //LatestCommitSha: entryCommit.ID.String(),
// Created: entryCommit.Author.When.Unix(),
// }
// break
// }
// }
// }
// // end by qiubing
//
// if err != nil {
// return nil, err
// }
// fileList = append(fileList, fileContentResponse)
// }
// log.Info("*****************GetContentsOrList.for-entries:%v", time.Now().Sub(start1))
// return fileList, nil
//}
//
//func GetContentsExt(gitRepo *git.Repository, commit *git.Commit, repo *models.Repository, treePath, ref string, forList bool) (*api.Wiki, error) {
// if ref == "" {
// ref = repo.DefaultBranch
// }
// origRef := ref
//
// // Check that the path given in opts.treePath is valid (not a git path)
// cleanTreePath := repofiles.CleanUploadFileName(treePath)
// if cleanTreePath == "" && treePath != "" {
// return nil, models.ErrFilenameInvalid{
// Path: treePath,
// }
// }
// treePath = cleanTreePath
// commitID := commit.ID.String()
// if len(ref) >= 4 && strings.HasPrefix(commitID, ref) {
// ref = commit.ID.String()
// }
// //start1:=time.Now()
// entry, err := commit.GetTreeEntryByPath(treePath)
// if err != nil {
// return nil, err
// }
// //fmt.Println("****GetContents.commit.GetTreeEntryByPath:",treePath," ",time.Now().Sub(start1))
// refType := gitRepo.GetRefType(ref)
// if refType == "invalid" {
// return nil, fmt.Errorf("no commit found for the ref [ref: %s]", ref)
// }
//
// selfURL, err := url.Parse(fmt.Sprintf("%s/contents/%s?ref=%s", repo.APIURL(), treePath, origRef))
// if err != nil {
// return nil, err
// }
// selfURLString := selfURL.String()
//
// // All content types have these fields in populated
// contentsResponse := &api.Wiki{
// Name: entry.Name(),
// Path: treePath,
// //SHA: entry.ID.String(),
// Size: entry.Size(),
// URL: &selfURLString,
// //Links: &api.FileLinksResponse{
// // Self: &selfURLString,
// //},
//
// }
//
// // Now populate the rest of the ContentsResponse based on entry type
// if entry.IsRegular() || entry.IsExecutable() {
// contentsResponse.Type = string(ContentTypeRegular)
// if blobResponse, err := repofiles.GetBlobBySHA(repo, entry.ID.String()); err != nil {
// return nil, err
// } else if !forList {
// // We don't show the content if we are getting a list of FileContentResponses
// contentsResponse.Encoding = &blobResponse.Encoding
// contentsResponse.Content = &blobResponse.Content
// }
// } else if entry.IsDir() {
// contentsResponse.Type = string(ContentTypeDir)
// } else if entry.IsLink() {
// contentsResponse.Type = string(ContentTypeLink)
// // The target of a symlink file is the content of the file
// //targetFromContent, err := entry.Blob().GetBlobContent()
// //if err != nil {
// // return nil, err
// //}
// ////contentsResponse.Target = &targetFromContent
// //} else if entry.IsSubModule() {
// // contentsResponse.Type = string(ContentTypeSubmodule)
// // submodule, err := commit.GetSubModule(treePath)
// // if err != nil {
// // return nil, err
// // }
// //if submodule != nil {
// // contentsResponse.SubmoduleGitURL = &submodule.URL
// //}
// }
// // Handle links
// if entry.IsRegular() || entry.IsLink() {
// downloadURL, err := url.Parse(fmt.Sprintf("%s/raw/%s/%s/%s", repo.HTMLURL(), refType, ref, treePath))
// if err != nil {
// return nil, err
// }
// downloadURLString := downloadURL.String()
// contentsResponse.DownloadURL = &downloadURLString
// }
// if !entry.IsSubModule() {
// htmlURL, err := url.Parse(fmt.Sprintf("%s/src/%s/%s/%s", repo.HTMLURL(), refType, ref, treePath))
// if err != nil {
// return nil, err
// }
// htmlURLString := htmlURL.String()
// contentsResponse.HTMLURL = &htmlURLString
// //contentsResponse.Links.HTMLURL = &htmlURLString
//
// gitURL, err := url.Parse(fmt.Sprintf("%s/git/blobs/%s", repo.APIURL(), entry.ID.String()))
// if err != nil {
// return nil, err
// }
// gitURLString := gitURL.String()
// contentsResponse.GitURL = &gitURLString
// //contentsResponse.Links.GitURL = &gitURLString
// }
//
// return contentsResponse, nil
//}
func FindWikiRepoCommit(ctx *context.APIContext) (*git.Repository, *git.Commit, error) {
wikiRepo, err := git.OpenRepository(ctx.Repo.Repository.WikiPath())
if err != nil {
ctx.ServerError("OpenRepository", err)
return nil, nil, err
}
commit, err := wikiRepo.GetBranchCommit("master")
if err != nil {
return wikiRepo, nil, err
}
return wikiRepo, commit, nil
}
func WikiContentsByName(ctx *context.APIContext, commit *git.Commit, wikiName string) ([]byte, *git.TreeEntry, string, bool) {
pageFilename := wiki_service.NameToFilename(wikiName)
entry, err := findEntryForFile(commit, pageFilename)
if err != nil && !git.IsErrNotExist(err) {
ctx.ServerError("findEntryForFile", err)
return nil, nil, "", false
} else if entry == nil {
return nil, nil, "", true
}
return wikiContentsByEntry(ctx, entry), entry, pageFilename, false
}
func findEntryForFile(commit *git.Commit, target string) (*git.TreeEntry, error) {
entry, err := commit.GetTreeEntryByPath(target)
if err != nil && !git.IsErrNotExist(err) {
return nil, err
}
if entry != nil {
return entry, nil
}
// Then the unescaped, shortest alternative
var unescapedTarget string
if unescapedTarget, err = url.QueryUnescape(target); err != nil {
return nil, err
}
return commit.GetTreeEntryByPath(unescapedTarget)
}
func wikiContentsByEntry(ctx *context.APIContext, entry *git.TreeEntry) []byte {
reader, err := entry.Blob().DataAsync()
if err != nil {
ctx.ServerError("Blob.Data", err)
return nil
}
defer reader.Close()
content, err := ioutil.ReadAll(reader)
if err != nil {
ctx.ServerError("ReadAll", err)
return nil
}
return content
}
//func (repo *models.Repository) ComposeDocumentMetas() map[string]string {
// if len(repo.DocumentRenderingMetas) == 0 {
// metas := map[string]string{}
// for k, v := range repo.ComposeMetas() {
// metas[k] = v
// }
// metas["mode"] = "document"
// repo.DocumentRenderingMetas = metas
// }
// return repo.DocumentRenderingMetas
//}

View File

@ -518,6 +518,7 @@ func mustNotBeArchived(ctx *context.APIContext) {
func RegisterRoutes(m *macaron.Macaron) {
bind := binding.Bind
//reqSignIn := context.Toggle(&context.ToggleOptions{SignInRequired: true})
// add by qiubing
reqRepoCodeReader := context.RequireRepoReader(models.UnitTypeCode)
// end by qiubing
@ -653,9 +654,10 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Combo("/repositories/:id", reqToken()).Get(repo.GetByID)
//reqRepoWikiWriter := context.RequireRepoWriter(models.UnitTypeWiki)
//
m.Group("/repos", func() {
m.Get("/search", repo.Search)
m.Get("/issues/search", repo.SearchIssues)
@ -675,6 +677,7 @@ func RegisterRoutes(m *macaron.Macaron) {
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
@ -704,6 +707,22 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Combo("/notifications").
Get(reqToken(), notify.ListRepoNotifications).
Put(reqToken(), notify.ReadRepoNotifications)
m.Group("/wiki", func() {
//m.Get("/*", repo.CreateNewWiki)
//m.Group("/:id",func(){
// m.Get("/wiki", repo.ListWiki)
//})
m.Group("/content", func() {
m.Get("/?:page",repo.WikiContent)
})
m.Get("/_pages", repo.WikiPages)
m.Group("", func() {
m.Get("/_new", repo.CreateNewWiki)
m.Get("/:page/_edit",repo.EditWiki)
})
})
m.Group("/hooks", func() {
m.Combo("").Get(repo.ListHooks).
Post(bind(api.CreateHookOption{}), repo.CreateHook)
@ -712,10 +731,9 @@ func RegisterRoutes(m *macaron.Macaron) {
Patch(bind(api.EditHookOption{}), repo.EditHook).
Delete(repo.DeleteHook)
m.Post("/tests", context.RepoRef(), repo.TestHook)
m.Get("/hooktasks",repo.HookTaskList)
})
m.Group("/hooktasks", func(){
m.Get("",repo.HookTaskList)
})
m.Group("/git", func() {
m.Combo("").Get(repo.ListGitHooks)
m.Group("/:id", func() {

257
routers/api/v1/repo/wiki.go Normal file
View File

@ -0,0 +1,257 @@
package repo
//
import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/markup/markdown"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/wikis"
wiki_service "code.gitea.io/gitea/services/wiki"
"fmt"
//"fmt"
//"golang.org/x/sys/windows"
"net/http"
//"time"
)
type PageMeta struct {
Name string `json:"name"`
SubURL string `json:"sub_url"`
UpdatedUnix timeutil.TimeStamp `json:"updated_unix"`
}
type Wiki struct {
WikiRepo *git.Repository `json:"wiki_repo"`
//CommitID *git.Commit `json:"commit_id"`
Page []PageMeta `json:"page"`
}
type wiContent struct{
UserName string `json:"user_name"`
UserId int64 `json:"user_id"`
PageName string `json:"page_name"`
UpdateUnix timeutil.TimeStamp `json:"update_unix"`
CommitCounts int64 `json:"commit_counts"`
Content string `json:"content"`
}
func WikiPages(ctx *context.APIContext) {
// swagger:operation GET /repos/{owner}/{repo}/wiki/_pages wikipages
// ---
// summary: Get ListWikiPages
// 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/Wiki/_page"
wikiRepo, commit, err := wikis.FindWikiRepoCommit(ctx)
fmt.Println("wikirepo = ",wikiRepo)
fmt.Println("commit = ", commit)
fmt.Println("err = ", err)
entries, err := commit.ListEntries()
if err != nil {
if wikiRepo != nil {
wikiRepo.Close()
}
ctx.NotFound("ListEntries", err)
return
}
pages := make([]PageMeta, 0, len(entries))
for _, entry := range entries {
if !entry.IsRegular() {
continue
}
c, err := wikiRepo.GetCommitByPath(entry.Name())
if err != nil {
if wikiRepo != nil {
wikiRepo.Close()
}
ctx.ServerError("GetCommit", err)
return
}
wikiName, err := wiki_service.FilenameToName(entry.Name())
if err != nil {
if models.IsErrWikiInvalidFileName(err) {
continue
}
if wikiRepo != nil {
wikiRepo.Close()
}
ctx.ServerError("WikiFilenameToName", err)
return
}
pages = append(pages,PageMeta{
Name: wikiName,
SubURL: wiki_service.NameToSubURL(wikiName),
UpdatedUnix: timeutil.TimeStamp(c.Author.When.Unix()),
})
}
WikiPages := Wiki{
WikiRepo: wikiRepo,
//CommitID: commit,
Page: pages,
}
//wikiPages, _ := json.Marshal(WikiPages)
ctx.JSON(http.StatusOK,WikiPages)
}
func WikiContent(ctx *context.APIContext){
// swagger:operation GET /repos/{owner}/{repo}/wiki/content/{pagename} wikiName Content
// ---
// summary: Get NameWiki Content
// 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: pagename
// in: path
// description: name of the wikipage
// type: string
// required: true
// responses:
// "200":
// "$ref": "#/responses/Wiki/content/wikipage"
wikiRepo, commit, _ := wikis.FindWikiRepoCommit(ctx)
//entries, err := commit.ListEntries()
//if err != nil {
// if wikiRepo != nil {
// wikiRepo.Close()
// }
//
// ctx.NotFound("ListEntries", err)
// return
//}
pageName := wiki_service.NormalizeWikiName(ctx.Params(":page"))
if len(pageName) == 0 {
pageName = "Home"
}
data, entry, pageFilename, noEntry := wikis.WikiContentsByName(ctx, commit, pageName)
if noEntry {
ctx.Redirect(ctx.Repo.RepoLink + "/wiki/_pages")
//ctx.ServerError("WikiContentsByName",error)
}
if entry == nil || ctx.Written() {
if wikiRepo != nil {
wikiRepo.Close()
}
}
metas := ctx.Repo.Repository.ComposeDocumentMetas()
PagaContent := markdown.RenderWiki(data, ctx.Repo.RepoLink, metas)
c, err := wikiRepo.GetCommitByPath(entry.Name())
if err != nil {
if models.IsErrWikiInvalidFileName(err) {
return
}
}
commitsCount, _ := wikiRepo.FileCommitsCount("master", pageFilename)
WikiPageContent := wiContent{
UserName: ctx.User.Name,
UserId: ctx.User.ID,
PageName: pageName,
UpdateUnix: timeutil.TimeStamp(c.Author.When.Unix()),
CommitCounts: commitsCount,
Content: PagaContent,
}
ctx.JSON(http.StatusOK,WikiPageContent)
}
func CreateNewWiki(ctx *context.APIContext){
// swagger:operation GET /repos/{owner}/{repo}/wiki/{pagename} Create a new Wikipage
// ---
// summary: wiki Content
// 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: pagename
// in: path
// description: path of the dir, file, symlink or submodule in the repo
// type: string
// required: true
// - name: ref
// in: query
// description: "The name of the commit/branch/tag. Default the repositorys default branch (usually master)"
// type: string
// required: false
// responses:
// "200":
// "$ref": "#/responses/ContentsResponse"
// "404":
// "$ref": "#/responses/notFound"
}
func EditWiki(ctx *context.Context){
// swagger:operation GET /repos/{owner}/{repo}/wiki/{pagename}/_edit Edit wikipage
// ---
// summary: new wiki
// 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: pagename
// in: path
// description: name of the wiki
// type: string
// required: true
// responses:
// "200":
// "$ref": "#/responses/Wiki/pagename/_edit"
}