forked from Gitlink/gitea_hat
新增:新建wiki接口
This commit is contained in:
parent
1eeb49801f
commit
905811e11e
|
@ -1,9 +1,14 @@
|
|||
package hat
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
hat_api "code.gitlink.org.cn/Gitlink/gitea_hat.git/modules/structs"
|
||||
"gitea.com/go-chi/binding"
|
||||
|
||||
access_model "code.gitea.io/gitea/models/perm/access"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
|
@ -54,7 +59,8 @@ func Routers() *web.Route {
|
|||
|
||||
m.Get("/tag_name_set", context.ReferencesGitRepo(), repo.TagNameSet)
|
||||
m.Group("/wikies", func() {
|
||||
m.Combo("").Get(repo.ListWikiPages)
|
||||
m.Combo("").Get(repo.ListWikiPages).
|
||||
Post(bind(hat_api.WikiOption{}), repo.CreateWiki)
|
||||
})
|
||||
}, repoAssignment())
|
||||
})
|
||||
|
@ -153,3 +159,20 @@ func repoAssignment() func(ctx *context.APIContext) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// bind binding an obj to a func(ctx *context.APIContext)
|
||||
func bind(obj interface{}) http.HandlerFunc {
|
||||
tp := reflect.TypeOf(obj)
|
||||
for tp.Kind() == reflect.Ptr {
|
||||
tp = tp.Elem()
|
||||
}
|
||||
return web.Wrap(func(ctx *context.APIContext) {
|
||||
theObj := reflect.New(tp).Interface() // create a new form obj for every request but not use obj directly
|
||||
errs := binding.Bind(ctx.Req, theObj)
|
||||
if len(errs) > 0 {
|
||||
ctx.Error(http.StatusUnprocessableEntity, "validationError", fmt.Sprintf("%s: %s", errs[0].FieldNames, errs[0].Error()))
|
||||
return
|
||||
}
|
||||
web.SetForm(ctx, theObj)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,12 +1,19 @@
|
|||
package repo
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/markup"
|
||||
"code.gitea.io/gitea/modules/markup/markdown"
|
||||
"code.gitea.io/gitea/modules/web"
|
||||
wiki_service "code.gitea.io/gitea/services/wiki"
|
||||
hat_git "code.gitlink.org.cn/Gitlink/gitea_hat.git/modules/git"
|
||||
hat_api "code.gitlink.org.cn/Gitlink/gitea_hat.git/modules/structs"
|
||||
|
@ -112,3 +119,122 @@ func findWikiRepoCommit(ctx *context.Context) (*git.Repository, *git.Commit, err
|
|||
}
|
||||
return wikiRepo, commit, nil
|
||||
}
|
||||
|
||||
func CreateWiki(ctx *context.Context) {
|
||||
form := web.GetForm(ctx).(*hat_api.WikiOption)
|
||||
|
||||
wikiName := wiki_service.NormalizeWikiName(form.Name)
|
||||
wikiCloneLink := ctx.Repo.Repository.WikiCloneLink()
|
||||
|
||||
if err := wiki_service.AddWikiPage(ctx, ctx.Doer, ctx.Repo.Repository, wikiName, form.Content, form.CommitMessage); err != nil {
|
||||
if models.IsErrWikiReservedName(err) {
|
||||
ctx.Error(http.StatusInternalServerError, "WikiNameIsReservedPage", "wiki名称是被保留的.")
|
||||
} else if models.IsErrWikiAlreadyExist(err) {
|
||||
ctx.Error(http.StatusConflict, "WikiNameAlreadyExist", "wiki名称已存在")
|
||||
} else {
|
||||
ctx.Error(http.StatusInternalServerError, "AddWikiPage", err.Error())
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
wikiRepo, commit, _ := findWikiRepoCommit(ctx)
|
||||
data, entry, pageFilename := wikiContentsByName(ctx, commit, wikiName)
|
||||
metas := ctx.Repo.Repository.ComposeDocumentMetas()
|
||||
|
||||
var rctx = &markup.RenderContext{
|
||||
URLPrefix: ctx.Repo.RepoLink,
|
||||
Metas: metas,
|
||||
IsWiki: true,
|
||||
}
|
||||
|
||||
var buf strings.Builder
|
||||
if err := markdown.Render(rctx, bytes.NewReader(data), &buf); err != nil {
|
||||
if wikiRepo != nil {
|
||||
wikiRepo.Close()
|
||||
}
|
||||
ctx.ServerError("Render", err)
|
||||
return
|
||||
}
|
||||
|
||||
commitsCount, _ := wikiRepo.FileCommitsCount("master", pageFilename)
|
||||
c, err := wikiRepo.GetCommitByPath(entry.Name())
|
||||
if err != nil {
|
||||
if models.IsErrWikiInvalidFileName(err) {
|
||||
return
|
||||
}
|
||||
}
|
||||
wiki := hat_api.WikiResponse{
|
||||
WikiCloneLink: hat_api.CloneLink{
|
||||
HTTPS: wikiCloneLink.HTTPS,
|
||||
SSH: wikiCloneLink.SSH,
|
||||
},
|
||||
WikiMeta: hat_api.WikiMeta{
|
||||
Name: form.Name,
|
||||
Commit: hat_api.WikiCommit{
|
||||
Author: hat_api.WikiUser{
|
||||
Name: c.Author.Name,
|
||||
Email: c.Author.Email,
|
||||
When: c.Author.When.Unix(),
|
||||
},
|
||||
Commiter: hat_api.WikiUser{
|
||||
Name: c.Committer.Name,
|
||||
Email: c.Committer.Email,
|
||||
When: c.Author.When.Unix(),
|
||||
},
|
||||
ID: c.ID.String(),
|
||||
Message: c.Message(),
|
||||
},
|
||||
},
|
||||
CommitCounts: commitsCount,
|
||||
MdContent: string(data),
|
||||
SimpleContent: buf.String(),
|
||||
}
|
||||
ctx.JSON(http.StatusOK, wiki)
|
||||
}
|
||||
|
||||
func wikiContentsByEntry(ctx *context.Context, entry *git.TreeEntry) []byte {
|
||||
reader, err := entry.Blob().DataAsync()
|
||||
if err != nil {
|
||||
ctx.ServerError("Blob.Data", err)
|
||||
return nil
|
||||
}
|
||||
defer reader.Close()
|
||||
content, err := io.ReadAll(reader)
|
||||
if err != nil {
|
||||
ctx.ServerError("ReadAll", err)
|
||||
return nil
|
||||
}
|
||||
return content
|
||||
}
|
||||
|
||||
func findEntryForFile(commit *git.Commit, target string) (*git.TreeEntry, error) {
|
||||
entry, err := commit.GetTreeEntryByPath(target)
|
||||
if err != nil {
|
||||
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)
|
||||
}
|
||||
|
||||
// wikiContentsByName returns the contents of a wiki page, along with a boolean
|
||||
// indicating whether the page exists. Writes to ctx if an error occurs.
|
||||
func wikiContentsByName(ctx *context.Context, commit *git.Commit, wikiName string) ([]byte, *git.TreeEntry, string) {
|
||||
pageFilename := wiki_service.NameToFilename(wikiName)
|
||||
entry, err := findEntryForFile(commit, pageFilename)
|
||||
if err != nil {
|
||||
if git.IsErrNotExist(err) {
|
||||
} else {
|
||||
ctx.ServerError("findEntryForFile", err)
|
||||
}
|
||||
return nil, nil, ""
|
||||
}
|
||||
return wikiContentsByEntry(ctx, entry), entry, pageFilename
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue