add: CreaeWiki
This commit is contained in:
parent
4884fe093f
commit
75627d0ceb
|
@ -783,8 +783,8 @@ func Routes() *web.Route {
|
||||||
})
|
})
|
||||||
}, reqToken(), reqAdmin())
|
}, reqToken(), reqAdmin())
|
||||||
m.Group("/wikies", func() {
|
m.Group("/wikies", func() {
|
||||||
m.Combo("").Get(repo.ListWikiPages)
|
m.Combo("").Get(repo.ListWikiPages).
|
||||||
// Post(bind(api.WikiOption{}), repo.CreateWiki)
|
Post(bind(api.WikiOption{}), repo.CreateWiki)
|
||||||
// m.Group("/:page", func() {
|
// m.Group("/:page", func() {
|
||||||
// m.Combo("").Get(repo.GetWiki).
|
// m.Combo("").Get(repo.GetWiki).
|
||||||
// Patch(bind(api.WikiOption{}), repo.EditWiki).
|
// Patch(bind(api.WikiOption{}), repo.EditWiki).
|
||||||
|
|
|
@ -1,13 +1,18 @@
|
||||||
package repo
|
package repo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"bytes"
|
||||||
"sort"
|
|
||||||
|
|
||||||
"code.gitea.io/gitea/models"
|
"code.gitea.io/gitea/models"
|
||||||
"code.gitea.io/gitea/modules/context"
|
"code.gitea.io/gitea/modules/context"
|
||||||
|
"code.gitea.io/gitea/modules/markup"
|
||||||
|
"code.gitea.io/gitea/modules/markup/markdown"
|
||||||
api "code.gitea.io/gitea/modules/structs"
|
api "code.gitea.io/gitea/modules/structs"
|
||||||
|
"code.gitea.io/gitea/modules/web"
|
||||||
webWiki "code.gitea.io/gitea/routers/web/repo"
|
webWiki "code.gitea.io/gitea/routers/web/repo"
|
||||||
|
"net/http"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
|
||||||
wiki_service "code.gitea.io/gitea/services/wiki"
|
wiki_service "code.gitea.io/gitea/services/wiki"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -117,5 +122,106 @@ func ListWikiPages(ctx *context.APIContext) {
|
||||||
return pages[i].FirstCommit.Author.When > pages[j].FirstCommit.Author.When
|
return pages[i].FirstCommit.Author.When > pages[j].FirstCommit.Author.When
|
||||||
})
|
})
|
||||||
ctx.JSON(http.StatusOK, pages)
|
ctx.JSON(http.StatusOK, pages)
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateWiki(ctx *context.APIContext) {
|
||||||
|
// swagger:operation POST /repos/{owner}/{repo}/wikies repository repoCreateWiki
|
||||||
|
// ---
|
||||||
|
// summary: Create a wiki in a repository
|
||||||
|
// 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: body
|
||||||
|
// in: body
|
||||||
|
// schema:
|
||||||
|
// "$ref": "#/definitions/WikiOption"
|
||||||
|
// responses:
|
||||||
|
// "200":
|
||||||
|
// "$ref": "#/responses/Wiki"
|
||||||
|
|
||||||
|
form := web.GetForm(ctx).(*api.WikiOption)
|
||||||
|
|
||||||
|
err := wiki_service.CheckFile(form.Name)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
wikiName := wiki_service.NormalizeWikiName(form.Name)
|
||||||
|
wikiCloneLink := ctx.Repo.Repository.WikiCloneLink()
|
||||||
|
|
||||||
|
if err := wiki_service.AddWikiPage(ctx.User, 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)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
wikiRepo, commit, _ := webWiki.FindWikiRepoCommit(ctx.Context)
|
||||||
|
data, entry, pageFilename, _ := webWiki.WikiContentsByName(ctx.Context, commit, form.Name)
|
||||||
|
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 := api.WikiResponse{
|
||||||
|
WikiCloneLink: api.CloneLink{
|
||||||
|
HTTPS: wikiCloneLink.HTTPS,
|
||||||
|
SSH: wikiCloneLink.SSH,
|
||||||
|
},
|
||||||
|
WikiMeta: api.WikiMeta{
|
||||||
|
Name: form.Name,
|
||||||
|
Commit: api.WikiCommit{
|
||||||
|
Author: api.WikiUser{
|
||||||
|
Name: c.Author.Name,
|
||||||
|
Email: c.Author.Email,
|
||||||
|
When: c.Author.When.Unix(),
|
||||||
|
},
|
||||||
|
Commiter: 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)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,9 @@ type swaggerParameterBodies struct {
|
||||||
// in:body
|
// in:body
|
||||||
DeleteEmailOption api.DeleteEmailOption
|
DeleteEmailOption api.DeleteEmailOption
|
||||||
|
|
||||||
|
// in:body
|
||||||
|
WikiOption api.WikiOption
|
||||||
|
|
||||||
// in:body
|
// in:body
|
||||||
CreateHookOption api.CreateHookOption
|
CreateHookOption api.CreateHookOption
|
||||||
// in:body
|
// in:body
|
||||||
|
|
|
@ -50,6 +50,10 @@ type swaggerResponseBranchProtectionList struct {
|
||||||
Body []api.BranchProtection `json:"body"`
|
Body []api.BranchProtection `json:"body"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type swaggerResponseWiki struct {
|
||||||
|
// in:body
|
||||||
|
Body api.WikiResponse `json:"body"`
|
||||||
|
}
|
||||||
type swaggerResponseWikiList struct {
|
type swaggerResponseWikiList struct {
|
||||||
// in:body
|
// in:body
|
||||||
Body api.WikiesResponse `json:"body"`
|
Body api.WikiesResponse `json:"body"`
|
||||||
|
|
|
@ -120,7 +120,7 @@ func wikiContentsByEntry(ctx *context.Context, entry *git.TreeEntry) []byte {
|
||||||
|
|
||||||
// wikiContentsByName returns the contents of a wiki page, along with a boolean
|
// wikiContentsByName returns the contents of a wiki page, along with a boolean
|
||||||
// indicating whether the page exists. Writes to ctx if an error occurs.
|
// 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, bool) {
|
func WikiContentsByName(ctx *context.Context, commit *git.Commit, wikiName string) ([]byte, *git.TreeEntry, string, bool) {
|
||||||
pageFilename := wiki_service.NameToFilename(wikiName)
|
pageFilename := wiki_service.NameToFilename(wikiName)
|
||||||
entry, err := findEntryForFile(commit, pageFilename)
|
entry, err := findEntryForFile(commit, pageFilename)
|
||||||
if err != nil && !git.IsErrNotExist(err) {
|
if err != nil && !git.IsErrNotExist(err) {
|
||||||
|
@ -190,7 +190,7 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
|
||||||
ctx.Data["RequireHighlightJS"] = true
|
ctx.Data["RequireHighlightJS"] = true
|
||||||
|
|
||||||
//lookup filename in wiki - get filecontent, gitTree entry , real filename
|
//lookup filename in wiki - get filecontent, gitTree entry , real filename
|
||||||
data, entry, pageFilename, noEntry := wikiContentsByName(ctx, commit, pageName)
|
data, entry, pageFilename, noEntry := WikiContentsByName(ctx, commit, pageName)
|
||||||
if noEntry {
|
if noEntry {
|
||||||
ctx.Redirect(ctx.Repo.RepoLink + "/wiki/_pages")
|
ctx.Redirect(ctx.Repo.RepoLink + "/wiki/_pages")
|
||||||
}
|
}
|
||||||
|
@ -201,7 +201,7 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
sidebarContent, _, _, _ := wikiContentsByName(ctx, commit, "_Sidebar")
|
sidebarContent, _, _, _ := WikiContentsByName(ctx, commit, "_Sidebar")
|
||||||
if ctx.Written() {
|
if ctx.Written() {
|
||||||
if wikiRepo != nil {
|
if wikiRepo != nil {
|
||||||
wikiRepo.Close()
|
wikiRepo.Close()
|
||||||
|
@ -209,7 +209,7 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
footerContent, _, _, _ := wikiContentsByName(ctx, commit, "_Footer")
|
footerContent, _, _, _ := WikiContentsByName(ctx, commit, "_Footer")
|
||||||
if ctx.Written() {
|
if ctx.Written() {
|
||||||
if wikiRepo != nil {
|
if wikiRepo != nil {
|
||||||
wikiRepo.Close()
|
wikiRepo.Close()
|
||||||
|
@ -288,7 +288,7 @@ func renderRevisionPage(ctx *context.Context) (*git.Repository, *git.TreeEntry)
|
||||||
ctx.Data["Reponame"] = ctx.Repo.Repository.Name
|
ctx.Data["Reponame"] = ctx.Repo.Repository.Name
|
||||||
|
|
||||||
//lookup filename in wiki - get filecontent, gitTree entry , real filename
|
//lookup filename in wiki - get filecontent, gitTree entry , real filename
|
||||||
data, entry, pageFilename, noEntry := wikiContentsByName(ctx, commit, pageName)
|
data, entry, pageFilename, noEntry := WikiContentsByName(ctx, commit, pageName)
|
||||||
if noEntry {
|
if noEntry {
|
||||||
ctx.Redirect(ctx.Repo.RepoLink + "/wiki/_pages")
|
ctx.Redirect(ctx.Repo.RepoLink + "/wiki/_pages")
|
||||||
}
|
}
|
||||||
|
@ -365,7 +365,7 @@ func renderEditPage(ctx *context.Context) {
|
||||||
ctx.Data["RequireHighlightJS"] = true
|
ctx.Data["RequireHighlightJS"] = true
|
||||||
|
|
||||||
//lookup filename in wiki - get filecontent, gitTree entry , real filename
|
//lookup filename in wiki - get filecontent, gitTree entry , real filename
|
||||||
data, entry, _, noEntry := wikiContentsByName(ctx, commit, pageName)
|
data, entry, _, noEntry := WikiContentsByName(ctx, commit, pageName)
|
||||||
if noEntry {
|
if noEntry {
|
||||||
ctx.Redirect(ctx.Repo.RepoLink + "/wiki/_pages")
|
ctx.Redirect(ctx.Repo.RepoLink + "/wiki/_pages")
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,17 +6,17 @@
|
||||||
package wiki
|
package wiki
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"net/url"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"code.gitea.io/gitea/models"
|
"code.gitea.io/gitea/models"
|
||||||
"code.gitea.io/gitea/modules/git"
|
"code.gitea.io/gitea/modules/git"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
repo_module "code.gitea.io/gitea/modules/repository"
|
repo_module "code.gitea.io/gitea/modules/repository"
|
||||||
"code.gitea.io/gitea/modules/sync"
|
"code.gitea.io/gitea/modules/sync"
|
||||||
"code.gitea.io/gitea/modules/util"
|
"code.gitea.io/gitea/modules/util"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -64,6 +64,16 @@ func FilenameToName(filename string) (string, error) {
|
||||||
return NormalizeWikiName(unescaped), nil
|
return NormalizeWikiName(unescaped), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check filename
|
||||||
|
func CheckFile(filename string) error {
|
||||||
|
if len(filename) <= 150 {
|
||||||
|
return nil
|
||||||
|
} else {
|
||||||
|
err := errors.New("The name is too long, please be less than 200 bytes")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// InitWiki initializes a wiki for repository,
|
// InitWiki initializes a wiki for repository,
|
||||||
// it does nothing when repository already has wiki.
|
// it does nothing when repository already has wiki.
|
||||||
func InitWiki(repo *models.Repository) error {
|
func InitWiki(repo *models.Repository) error {
|
||||||
|
|
|
@ -9808,6 +9808,44 @@
|
||||||
"$ref": "#/responses/WikiList"
|
"$ref": "#/responses/WikiList"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"post": {
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"repository"
|
||||||
|
],
|
||||||
|
"summary": "Create a wiki in a repository",
|
||||||
|
"operationId": "repoCreateWiki",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "owner of the repo",
|
||||||
|
"name": "owner",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "name of the repo",
|
||||||
|
"name": "repo",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "body",
|
||||||
|
"in": "body",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/WikiOption"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"$ref": "#/responses/Wiki"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/repos/{template_owner}/{template_repo}/generate": {
|
"/repos/{template_owner}/{template_repo}/generate": {
|
||||||
|
@ -17075,6 +17113,24 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"x-go-package": "code.gitea.io/gitea/modules/structs"
|
"x-go-package": "code.gitea.io/gitea/modules/structs"
|
||||||
|
},
|
||||||
|
"WikiOption": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"commit_message": {
|
||||||
|
"type": "string",
|
||||||
|
"x-go-name": "CommitMessage"
|
||||||
|
},
|
||||||
|
"content": {
|
||||||
|
"type": "string",
|
||||||
|
"x-go-name": "Content"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"x-go-name": "Name"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-go-package": "code.gitea.io/gitea/modules/structs"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"responses": {
|
"responses": {
|
||||||
|
|
Loading…
Reference in New Issue