2015-11-26 04:10:25 +03:00
// Copyright 2015 The Gogs Authors. All rights reserved.
2018-11-28 14:26:14 +03:00
// Copyright 2018 The Gitea Authors. All rights reserved.
2015-11-26 04:10:25 +03:00
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package repo
import (
2017-02-14 04:13:59 +03:00
"fmt"
2015-11-27 08:24:24 +03:00
"io/ioutil"
2019-10-09 21:49:37 +03:00
"net/url"
2017-02-14 04:13:59 +03:00
"path/filepath"
2015-11-27 09:50:38 +03:00
"strings"
2015-11-27 08:24:24 +03:00
2016-11-10 19:24:48 +03:00
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/auth"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/context"
2019-03-27 12:33:00 +03:00
"code.gitea.io/gitea/modules/git"
2019-04-22 23:40:51 +03:00
"code.gitea.io/gitea/modules/log"
2017-04-21 10:01:08 +03:00
"code.gitea.io/gitea/modules/markup"
2017-09-21 08:20:14 +03:00
"code.gitea.io/gitea/modules/markup/markdown"
2019-08-15 17:46:21 +03:00
"code.gitea.io/gitea/modules/timeutil"
2017-12-13 16:46:56 +03:00
"code.gitea.io/gitea/modules/util"
2020-01-07 21:27:36 +03:00
wiki_service "code.gitea.io/gitea/services/wiki"
2015-11-26 04:10:25 +03:00
)
const (
2019-07-08 11:20:22 +03:00
tplWikiStart base . TplName = "repo/wiki/start"
tplWikiView base . TplName = "repo/wiki/view"
tplWikiRevision base . TplName = "repo/wiki/revision"
tplWikiNew base . TplName = "repo/wiki/new"
tplWikiPages base . TplName = "repo/wiki/pages"
2015-11-26 04:10:25 +03:00
)
2016-11-21 13:03:42 +03:00
// MustEnableWiki check if wiki is enabled, if external then redirect
2016-03-11 19:56:52 +03:00
func MustEnableWiki ( ctx * context . Context ) {
2018-11-28 14:26:14 +03:00
if ! ctx . Repo . CanRead ( models . UnitTypeWiki ) &&
! ctx . Repo . CanRead ( models . UnitTypeExternalWiki ) {
2019-04-22 23:40:51 +03:00
if log . IsTrace ( ) {
log . Trace ( "Permission Denied: User %-v cannot read %-v or %-v of repo %-v\n" +
"User in repo has Permissions: %-+v" ,
ctx . User ,
models . UnitTypeWiki ,
models . UnitTypeExternalWiki ,
ctx . Repo . Repository ,
ctx . Repo . Permission )
}
2018-01-11 00:34:17 +03:00
ctx . NotFound ( "MustEnableWiki" , nil )
2015-12-11 12:55:08 +03:00
return
}
2017-02-04 18:53:46 +03:00
unit , err := ctx . Repo . Repository . GetUnit ( models . UnitTypeExternalWiki )
if err == nil {
ctx . Redirect ( unit . ExternalWikiConfig ( ) . ExternalWikiURL )
2015-12-11 12:55:08 +03:00
return
2015-12-05 05:30:33 +03:00
}
}
2019-10-02 23:02:04 +03:00
// PageMeta wiki page meta information
2015-11-27 09:50:38 +03:00
type PageMeta struct {
2017-12-13 16:46:56 +03:00
Name string
SubURL string
2019-08-15 17:46:21 +03:00
UpdatedUnix timeutil . TimeStamp
2015-11-27 09:50:38 +03:00
}
2015-11-26 04:10:25 +03:00
2017-11-28 12:43:51 +03:00
// findEntryForFile finds the tree entry for a target filepath.
func findEntryForFile ( commit * git . Commit , target string ) ( * git . TreeEntry , error ) {
2020-01-28 12:44:08 +03:00
entry , err := commit . GetTreeEntryByPath ( target )
if err != nil && ! git . IsErrNotExist ( err ) {
2017-02-14 04:13:59 +03:00
return nil , err
}
2020-01-28 12:44:08 +03:00
if entry != nil {
return entry , nil
2017-02-14 04:13:59 +03:00
}
2020-01-28 12:44:08 +03:00
2019-10-09 21:49:37 +03:00
// Then the unescaped, shortest alternative
var unescapedTarget string
if unescapedTarget , err = url . QueryUnescape ( target ) ; err != nil {
return nil , err
}
2020-01-28 12:44:08 +03:00
return commit . GetTreeEntryByPath ( unescapedTarget )
2017-02-14 04:13:59 +03:00
}
func findWikiRepoCommit ( ctx * context . Context ) ( * git . Repository , * git . Commit , error ) {
2015-11-27 08:24:24 +03:00
wikiRepo , err := git . OpenRepository ( ctx . Repo . Repository . WikiPath ( ) )
if err != nil {
2018-01-11 00:34:17 +03:00
ctx . ServerError ( "OpenRepository" , err )
2017-02-14 04:13:59 +03:00
return nil , nil , err
2015-11-27 08:24:24 +03:00
}
2017-03-20 16:36:19 +03:00
2015-12-10 04:46:05 +03:00
commit , err := wikiRepo . GetBranchCommit ( "master" )
2015-11-27 08:24:24 +03:00
if err != nil {
2017-02-14 04:13:59 +03:00
return wikiRepo , nil , err
}
return wikiRepo , commit , nil
}
2017-11-28 12:43:51 +03:00
// wikiContentsByEntry returns the contents of the wiki page referenced by the
// given tree entry. Writes to ctx if an error occurs.
func wikiContentsByEntry ( ctx * context . Context , entry * git . TreeEntry ) [ ] byte {
2019-04-19 15:17:27 +03:00
reader , err := entry . Blob ( ) . DataAsync ( )
2017-11-28 12:43:51 +03:00
if err != nil {
2018-01-11 00:34:17 +03:00
ctx . ServerError ( "Blob.Data" , err )
2017-11-28 12:43:51 +03:00
return nil
}
2019-04-19 15:17:27 +03:00
defer reader . Close ( )
2017-11-28 12:43:51 +03:00
content , err := ioutil . ReadAll ( reader )
if err != nil {
2018-01-11 00:34:17 +03:00
ctx . ServerError ( "ReadAll" , err )
2017-11-28 12:43:51 +03:00
return nil
}
return content
}
// wikiContentsByName returns the contents of a wiki page, along with a boolean
// indicating whether the page exists. Writes to ctx if an error occurs.
2019-07-08 11:20:22 +03:00
func wikiContentsByName ( ctx * context . Context , commit * git . Commit , wikiName string ) ( [ ] byte , * git . TreeEntry , string , bool ) {
2020-01-07 21:27:36 +03:00
pageFilename := wiki_service . NameToFilename ( wikiName )
2020-01-28 12:44:08 +03:00
entry , err := findEntryForFile ( commit , pageFilename )
if err != nil && ! git . IsErrNotExist ( err ) {
2018-01-11 00:34:17 +03:00
ctx . ServerError ( "findEntryForFile" , err )
2019-07-08 11:20:22 +03:00
return nil , nil , "" , false
2017-11-28 12:43:51 +03:00
} else if entry == nil {
2019-07-08 11:20:22 +03:00
return nil , nil , "" , true
2017-11-28 12:43:51 +03:00
}
2019-07-08 11:20:22 +03:00
return wikiContentsByEntry ( ctx , entry ) , entry , pageFilename , false
2017-11-28 12:43:51 +03:00
}
2019-07-08 11:20:22 +03:00
func renderViewPage ( ctx * context . Context ) ( * git . Repository , * git . TreeEntry ) {
2017-02-14 04:13:59 +03:00
wikiRepo , commit , err := findWikiRepoCommit ( ctx )
if err != nil {
2018-12-10 01:45:44 +03:00
if ! git . IsErrNotExist ( err ) {
ctx . ServerError ( "GetBranchCommit" , err )
}
2017-02-14 04:13:59 +03:00
return nil , nil
2015-11-27 09:50:38 +03:00
}
// Get page list.
2019-07-08 11:20:22 +03:00
entries , err := commit . ListEntries ( )
if err != nil {
2019-11-13 10:01:19 +03:00
if wikiRepo != nil {
wikiRepo . Close ( )
}
2019-07-08 11:20:22 +03:00
ctx . ServerError ( "ListEntries" , err )
return nil , nil
}
pages := make ( [ ] PageMeta , 0 , len ( entries ) )
for _ , entry := range entries {
if ! entry . IsRegular ( ) {
continue
2015-11-27 09:50:38 +03:00
}
2020-01-07 21:27:36 +03:00
wikiName , err := wiki_service . FilenameToName ( entry . Name ( ) )
2019-07-08 11:20:22 +03:00
if err != nil {
if models . IsErrWikiInvalidFileName ( err ) {
2017-11-28 12:43:51 +03:00
continue
}
2019-11-13 10:01:19 +03:00
if wikiRepo != nil {
wikiRepo . Close ( )
}
2019-07-08 11:20:22 +03:00
ctx . ServerError ( "WikiFilenameToName" , err )
return nil , nil
} else if wikiName == "_Sidebar" || wikiName == "_Footer" {
continue
2015-11-27 09:50:38 +03:00
}
2019-07-08 11:20:22 +03:00
pages = append ( pages , PageMeta {
Name : wikiName ,
2020-01-07 21:27:36 +03:00
SubURL : wiki_service . NameToSubURL ( wikiName ) ,
2019-07-08 11:20:22 +03:00
} )
2015-11-27 08:24:24 +03:00
}
2019-07-08 11:20:22 +03:00
ctx . Data [ "Pages" ] = pages
2015-11-27 08:24:24 +03:00
2019-07-08 11:20:22 +03:00
// get requested pagename
2020-01-07 21:27:36 +03:00
pageName := wiki_service . NormalizeWikiName ( ctx . Params ( ":page" ) )
2017-11-28 12:43:51 +03:00
if len ( pageName ) == 0 {
pageName = "Home"
2015-11-27 08:24:24 +03:00
}
2020-01-07 21:27:36 +03:00
ctx . Data [ "PageURL" ] = wiki_service . NameToSubURL ( pageName )
2015-11-27 09:50:38 +03:00
ctx . Data [ "old_title" ] = pageName
ctx . Data [ "Title" ] = pageName
ctx . Data [ "title" ] = pageName
2015-11-27 08:24:24 +03:00
ctx . Data [ "RequireHighlightJS" ] = true
2019-07-08 11:20:22 +03:00
//lookup filename in wiki - get filecontent, gitTree entry , real filename
data , entry , pageFilename , noEntry := wikiContentsByName ( ctx , commit , pageName )
if noEntry {
2017-02-14 04:13:59 +03:00
ctx . Redirect ( ctx . Repo . RepoLink + "/wiki/_pages" )
2019-07-08 11:20:22 +03:00
}
if entry == nil || ctx . Written ( ) {
2019-11-13 10:01:19 +03:00
if wikiRepo != nil {
wikiRepo . Close ( )
}
2017-02-14 04:13:59 +03:00
return nil , nil
2015-11-27 08:24:24 +03:00
}
2019-07-08 11:20:22 +03:00
sidebarContent , _ , _ , _ := wikiContentsByName ( ctx , commit , "_Sidebar" )
2017-11-28 12:43:51 +03:00
if ctx . Written ( ) {
2019-11-13 10:01:19 +03:00
if wikiRepo != nil {
wikiRepo . Close ( )
}
2017-02-14 04:13:59 +03:00
return nil , nil
}
2017-11-28 12:43:51 +03:00
2019-07-08 11:20:22 +03:00
footerContent , _ , _ , _ := wikiContentsByName ( ctx , commit , "_Footer" )
if ctx . Written ( ) {
2019-11-13 10:01:19 +03:00
if wikiRepo != nil {
wikiRepo . Close ( )
}
2019-07-08 11:20:22 +03:00
return nil , nil
}
2017-11-28 12:43:51 +03:00
2020-05-24 11:14:26 +03:00
metas := ctx . Repo . Repository . ComposeDocumentMetas ( )
2019-07-08 11:20:22 +03:00
ctx . Data [ "content" ] = markdown . RenderWiki ( data , ctx . Repo . RepoLink , metas )
ctx . Data [ "sidebarPresent" ] = sidebarContent != nil
ctx . Data [ "sidebarContent" ] = markdown . RenderWiki ( sidebarContent , ctx . Repo . RepoLink , metas )
ctx . Data [ "footerPresent" ] = footerContent != nil
ctx . Data [ "footerContent" ] = markdown . RenderWiki ( footerContent , ctx . Repo . RepoLink , metas )
// get commit count - wiki revisions
commitsCount , _ := wikiRepo . FileCommitsCount ( "master" , pageFilename )
ctx . Data [ "CommitCount" ] = commitsCount
return wikiRepo , entry
}
func renderRevisionPage ( ctx * context . Context ) ( * git . Repository , * git . TreeEntry ) {
wikiRepo , commit , err := findWikiRepoCommit ( ctx )
if err != nil {
2019-11-13 10:01:19 +03:00
if wikiRepo != nil {
wikiRepo . Close ( )
}
2019-07-08 11:20:22 +03:00
if ! git . IsErrNotExist ( err ) {
ctx . ServerError ( "GetBranchCommit" , err )
2017-02-14 04:13:59 +03:00
}
2019-07-08 11:20:22 +03:00
return nil , nil
}
// get requested pagename
2020-01-07 21:27:36 +03:00
pageName := wiki_service . NormalizeWikiName ( ctx . Params ( ":page" ) )
2019-07-08 11:20:22 +03:00
if len ( pageName ) == 0 {
pageName = "Home"
}
2020-01-07 21:27:36 +03:00
ctx . Data [ "PageURL" ] = wiki_service . NameToSubURL ( pageName )
2019-07-08 11:20:22 +03:00
ctx . Data [ "old_title" ] = pageName
ctx . Data [ "Title" ] = pageName
ctx . Data [ "title" ] = pageName
ctx . Data [ "RequireHighlightJS" ] = true
2020-05-16 19:38:40 +03:00
ctx . Data [ "Username" ] = ctx . Repo . Owner . Name
ctx . Data [ "Reponame" ] = ctx . Repo . Repository . Name
2017-11-28 12:43:51 +03:00
2019-07-08 11:20:22 +03:00
//lookup filename in wiki - get filecontent, gitTree entry , real filename
data , entry , pageFilename , noEntry := wikiContentsByName ( ctx , commit , pageName )
if noEntry {
ctx . Redirect ( ctx . Repo . RepoLink + "/wiki/_pages" )
}
if entry == nil || ctx . Written ( ) {
2019-11-13 10:01:19 +03:00
if wikiRepo != nil {
wikiRepo . Close ( )
}
2019-07-08 11:20:22 +03:00
return nil , nil
2015-11-27 09:50:38 +03:00
}
2019-07-08 11:20:22 +03:00
ctx . Data [ "content" ] = string ( data )
ctx . Data [ "sidebarPresent" ] = false
ctx . Data [ "sidebarContent" ] = ""
ctx . Data [ "footerPresent" ] = false
ctx . Data [ "footerContent" ] = ""
// get commit count - wiki revisions
commitsCount , _ := wikiRepo . FileCommitsCount ( "master" , pageFilename )
ctx . Data [ "CommitCount" ] = commitsCount
// get page
page := ctx . QueryInt ( "page" )
if page <= 1 {
page = 1
}
// get Commit Count
2019-07-11 17:45:10 +03:00
commitsHistory , err := wikiRepo . CommitsByFileAndRangeNoFollow ( "master" , pageFilename , page )
2019-07-08 11:20:22 +03:00
if err != nil {
2019-11-13 10:01:19 +03:00
if wikiRepo != nil {
wikiRepo . Close ( )
}
2019-07-11 17:45:10 +03:00
ctx . ServerError ( "CommitsByFileAndRangeNoFollow" , err )
2019-07-08 11:20:22 +03:00
return nil , nil
}
commitsHistory = models . ValidateCommitsWithEmails ( commitsHistory )
2020-02-27 22:20:55 +03:00
commitsHistory = models . ParseCommitsWithSignature ( commitsHistory , ctx . Repo . Repository )
2019-07-08 11:20:22 +03:00
ctx . Data [ "Commits" ] = commitsHistory
pager := context . NewPagination ( int ( commitsCount ) , git . CommitsRangeSize , page , 5 )
pager . SetDefaultParams ( ctx )
ctx . Data [ "Page" ] = pager
2017-02-14 04:13:59 +03:00
return wikiRepo , entry
2015-11-27 09:50:38 +03:00
}
2019-07-08 11:20:22 +03:00
func renderEditPage ( ctx * context . Context ) {
2019-11-13 10:01:19 +03:00
wikiRepo , commit , err := findWikiRepoCommit ( ctx )
2019-07-08 11:20:22 +03:00
if err != nil {
2019-11-13 10:01:19 +03:00
if wikiRepo != nil {
wikiRepo . Close ( )
}
2019-07-08 11:20:22 +03:00
if ! git . IsErrNotExist ( err ) {
ctx . ServerError ( "GetBranchCommit" , err )
}
return
}
2019-11-13 10:01:19 +03:00
defer func ( ) {
if wikiRepo != nil {
wikiRepo . Close ( )
}
} ( )
2019-07-08 11:20:22 +03:00
// get requested pagename
2020-01-07 21:27:36 +03:00
pageName := wiki_service . NormalizeWikiName ( ctx . Params ( ":page" ) )
2019-07-08 11:20:22 +03:00
if len ( pageName ) == 0 {
pageName = "Home"
}
2020-01-07 21:27:36 +03:00
ctx . Data [ "PageURL" ] = wiki_service . NameToSubURL ( pageName )
2019-07-08 11:20:22 +03:00
ctx . Data [ "old_title" ] = pageName
ctx . Data [ "Title" ] = pageName
ctx . Data [ "title" ] = pageName
ctx . Data [ "RequireHighlightJS" ] = true
//lookup filename in wiki - get filecontent, gitTree entry , real filename
data , entry , _ , noEntry := wikiContentsByName ( ctx , commit , pageName )
if noEntry {
ctx . Redirect ( ctx . Repo . RepoLink + "/wiki/_pages" )
}
if entry == nil || ctx . Written ( ) {
return
}
ctx . Data [ "content" ] = string ( data )
ctx . Data [ "sidebarPresent" ] = false
ctx . Data [ "sidebarContent" ] = ""
ctx . Data [ "footerPresent" ] = false
ctx . Data [ "footerContent" ] = ""
}
2017-02-14 04:13:59 +03:00
// Wiki renders single wiki page
2016-03-11 19:56:52 +03:00
func Wiki ( ctx * context . Context ) {
2015-11-27 09:50:38 +03:00
ctx . Data [ "PageIsWiki" ] = true
2019-01-23 21:58:38 +03:00
ctx . Data [ "CanWriteWiki" ] = ctx . Repo . CanWrite ( models . UnitTypeWiki ) && ! ctx . Repo . Repository . IsArchived
2015-11-27 09:50:38 +03:00
if ! ctx . Repo . Repository . HasWiki ( ) {
ctx . Data [ "Title" ] = ctx . Tr ( "repo.wiki" )
2016-11-21 13:03:42 +03:00
ctx . HTML ( 200 , tplWikiStart )
2015-11-27 09:50:38 +03:00
return
}
2019-07-08 11:20:22 +03:00
wikiRepo , entry := renderViewPage ( ctx )
2015-11-27 09:50:38 +03:00
if ctx . Written ( ) {
2019-11-13 10:01:19 +03:00
if wikiRepo != nil {
wikiRepo . Close ( )
}
2015-11-27 08:24:24 +03:00
return
}
2019-11-13 10:01:19 +03:00
defer func ( ) {
if wikiRepo != nil {
wikiRepo . Close ( )
}
} ( )
2017-03-20 16:36:19 +03:00
if entry == nil {
ctx . Data [ "Title" ] = ctx . Tr ( "repo.wiki" )
ctx . HTML ( 200 , tplWikiStart )
return
}
2015-11-27 08:24:24 +03:00
2017-11-28 12:43:51 +03:00
wikiPath := entry . Name ( )
if markup . Type ( wikiPath ) != markdown . MarkupName {
ext := strings . ToUpper ( filepath . Ext ( wikiPath ) )
2017-02-14 04:13:59 +03:00
ctx . Data [ "FormatWarning" ] = fmt . Sprintf ( "%s rendering is not supported at the moment. Rendered as Markdown." , ext )
}
2015-11-27 08:24:24 +03:00
// Get last change information.
2017-11-28 12:43:51 +03:00
lastCommit , err := wikiRepo . GetCommitByPath ( wikiPath )
2015-11-27 08:24:24 +03:00
if err != nil {
2018-01-11 00:34:17 +03:00
ctx . ServerError ( "GetCommitByPath" , err )
2015-11-27 08:24:24 +03:00
return
}
ctx . Data [ "Author" ] = lastCommit . Author
2016-11-21 13:03:42 +03:00
ctx . HTML ( 200 , tplWikiView )
2015-11-26 04:10:25 +03:00
}
2019-07-08 11:20:22 +03:00
// WikiRevision renders file revision list of wiki page
func WikiRevision ( ctx * context . Context ) {
ctx . Data [ "PageIsWiki" ] = true
ctx . Data [ "CanWriteWiki" ] = ctx . Repo . CanWrite ( models . UnitTypeWiki ) && ! ctx . Repo . Repository . IsArchived
if ! ctx . Repo . Repository . HasWiki ( ) {
ctx . Data [ "Title" ] = ctx . Tr ( "repo.wiki" )
ctx . HTML ( 200 , tplWikiStart )
return
}
wikiRepo , entry := renderRevisionPage ( ctx )
if ctx . Written ( ) {
2019-11-13 10:01:19 +03:00
if wikiRepo != nil {
wikiRepo . Close ( )
}
2019-07-08 11:20:22 +03:00
return
}
2019-11-13 10:01:19 +03:00
defer func ( ) {
if wikiRepo != nil {
wikiRepo . Close ( )
}
} ( )
2019-07-08 11:20:22 +03:00
if entry == nil {
ctx . Data [ "Title" ] = ctx . Tr ( "repo.wiki" )
ctx . HTML ( 200 , tplWikiStart )
return
}
// Get last change information.
wikiPath := entry . Name ( )
lastCommit , err := wikiRepo . GetCommitByPath ( wikiPath )
if err != nil {
ctx . ServerError ( "GetCommitByPath" , err )
return
}
ctx . Data [ "Author" ] = lastCommit . Author
ctx . HTML ( 200 , tplWikiRevision )
}
2016-11-21 13:03:42 +03:00
// WikiPages render wiki pages list page
2016-03-11 19:56:52 +03:00
func WikiPages ( ctx * context . Context ) {
2015-11-27 10:16:12 +03:00
if ! ctx . Repo . Repository . HasWiki ( ) {
ctx . Redirect ( ctx . Repo . RepoLink + "/wiki" )
return
}
2018-11-28 14:26:14 +03:00
ctx . Data [ "Title" ] = ctx . Tr ( "repo.wiki.pages" )
ctx . Data [ "PageIsWiki" ] = true
2019-01-23 21:58:38 +03:00
ctx . Data [ "CanWriteWiki" ] = ctx . Repo . CanWrite ( models . UnitTypeWiki ) && ! ctx . Repo . Repository . IsArchived
2018-11-28 14:26:14 +03:00
2017-02-14 04:13:59 +03:00
wikiRepo , commit , err := findWikiRepoCommit ( ctx )
2015-11-27 10:16:12 +03:00
if err != nil {
2019-11-13 10:01:19 +03:00
if wikiRepo != nil {
wikiRepo . Close ( )
}
2015-11-27 10:16:12 +03:00
return
}
entries , err := commit . ListEntries ( )
if err != nil {
2019-11-13 10:01:19 +03:00
if wikiRepo != nil {
wikiRepo . Close ( )
}
2018-01-11 00:34:17 +03:00
ctx . ServerError ( "ListEntries" , err )
2015-11-27 10:16:12 +03:00
return
}
pages := make ( [ ] PageMeta , 0 , len ( entries ) )
2017-11-28 12:43:51 +03:00
for _ , entry := range entries {
2019-04-19 15:17:27 +03:00
if ! entry . IsRegular ( ) {
2017-11-28 12:43:51 +03:00
continue
}
c , err := wikiRepo . GetCommitByPath ( entry . Name ( ) )
if err != nil {
2019-11-13 10:01:19 +03:00
if wikiRepo != nil {
wikiRepo . Close ( )
}
2018-01-11 00:34:17 +03:00
ctx . ServerError ( "GetCommit" , err )
2017-11-28 12:43:51 +03:00
return
}
2020-01-07 21:27:36 +03:00
wikiName , err := wiki_service . FilenameToName ( entry . Name ( ) )
2017-11-28 12:43:51 +03:00
if err != nil {
2018-02-05 17:56:30 +03:00
if models . IsErrWikiInvalidFileName ( err ) {
continue
}
2019-11-13 10:01:19 +03:00
if wikiRepo != nil {
wikiRepo . Close ( )
}
2018-01-11 00:34:17 +03:00
ctx . ServerError ( "WikiFilenameToName" , err )
2017-11-28 12:43:51 +03:00
return
2015-11-27 10:16:12 +03:00
}
2017-11-28 12:43:51 +03:00
pages = append ( pages , PageMeta {
2017-12-13 16:46:56 +03:00
Name : wikiName ,
2020-01-07 21:27:36 +03:00
SubURL : wiki_service . NameToSubURL ( wikiName ) ,
2019-08-15 17:46:21 +03:00
UpdatedUnix : timeutil . TimeStamp ( c . Author . When . Unix ( ) ) ,
2017-11-28 12:43:51 +03:00
} )
2015-11-27 10:16:12 +03:00
}
ctx . Data [ "Pages" ] = pages
2015-11-27 08:24:24 +03:00
2019-11-13 10:01:19 +03:00
defer func ( ) {
if wikiRepo != nil {
wikiRepo . Close ( )
}
} ( )
2016-11-21 13:03:42 +03:00
ctx . HTML ( 200 , tplWikiPages )
2015-11-27 08:24:24 +03:00
}
2017-02-14 04:13:59 +03:00
// WikiRaw outputs raw blob requested by user (image for example)
func WikiRaw ( ctx * context . Context ) {
wikiRepo , commit , err := findWikiRepoCommit ( ctx )
if err != nil {
if wikiRepo != nil {
return
}
}
2019-02-06 04:58:55 +03:00
2017-11-28 12:43:51 +03:00
providedPath := ctx . Params ( "*" )
2019-02-06 04:58:55 +03:00
2017-02-14 04:13:59 +03:00
var entry * git . TreeEntry
if commit != nil {
2019-02-06 04:58:55 +03:00
// Try to find a file with that name
entry , err = findEntryForFile ( commit , providedPath )
2020-01-28 12:44:08 +03:00
if err != nil && ! git . IsErrNotExist ( err ) {
2019-02-06 04:58:55 +03:00
ctx . ServerError ( "findFile" , err )
return
}
if entry == nil {
// Try to find a wiki page with that name
if strings . HasSuffix ( providedPath , ".md" ) {
providedPath = providedPath [ : len ( providedPath ) - 3 ]
}
2020-01-07 21:27:36 +03:00
wikiPath := wiki_service . NameToFilename ( providedPath )
2019-02-06 04:58:55 +03:00
entry , err = findEntryForFile ( commit , wikiPath )
2020-01-28 12:44:08 +03:00
if err != nil && ! git . IsErrNotExist ( err ) {
2019-02-06 04:58:55 +03:00
ctx . ServerError ( "findFile" , err )
return
}
}
2017-02-14 04:13:59 +03:00
}
2019-02-06 04:58:55 +03:00
if entry != nil {
if err = ServeBlob ( ctx , entry . Blob ( ) ) ; err != nil {
ctx . ServerError ( "ServeBlob" , err )
}
2017-11-28 12:43:51 +03:00
return
}
2019-02-06 04:58:55 +03:00
ctx . NotFound ( "findEntryForFile" , nil )
2017-02-14 04:13:59 +03:00
}
2016-11-21 13:03:42 +03:00
// NewWiki render wiki create page
2016-03-11 19:56:52 +03:00
func NewWiki ( ctx * context . Context ) {
2015-11-26 04:10:25 +03:00
ctx . Data [ "Title" ] = ctx . Tr ( "repo.wiki.new_page" )
ctx . Data [ "PageIsWiki" ] = true
ctx . Data [ "RequireSimpleMDE" ] = true
2015-11-27 01:33:45 +03:00
if ! ctx . Repo . Repository . HasWiki ( ) {
2015-11-26 04:10:25 +03:00
ctx . Data [ "title" ] = "Home"
}
2016-11-21 13:03:42 +03:00
ctx . HTML ( 200 , tplWikiNew )
2015-11-26 04:10:25 +03:00
}
2017-11-28 12:43:51 +03:00
// NewWikiPost response for wiki create request
2016-03-11 19:56:52 +03:00
func NewWikiPost ( ctx * context . Context , form auth . NewWikiForm ) {
2015-11-27 01:33:45 +03:00
ctx . Data [ "Title" ] = ctx . Tr ( "repo.wiki.new_page" )
ctx . Data [ "PageIsWiki" ] = true
ctx . Data [ "RequireSimpleMDE" ] = true
if ctx . HasError ( ) {
2016-11-21 13:03:42 +03:00
ctx . HTML ( 200 , tplWikiNew )
2015-11-27 01:33:45 +03:00
return
}
2019-01-21 14:45:32 +03:00
if util . IsEmptyString ( form . Title ) {
ctx . RenderWithErr ( ctx . Tr ( "repo.issues.new.title_empty" ) , tplWikiNew , form )
return
}
2020-01-07 21:27:36 +03:00
wikiName := wiki_service . NormalizeWikiName ( form . Title )
2020-05-22 16:14:02 +03:00
if len ( form . Message ) == 0 {
form . Message = ctx . Tr ( "repo.editor.add" , form . Title )
}
2020-01-07 21:27:36 +03:00
if err := wiki_service . AddWikiPage ( ctx . User , ctx . Repo . Repository , wikiName , form . Content , form . Message ) ; err != nil {
2017-11-28 12:43:51 +03:00
if models . IsErrWikiReservedName ( err ) {
ctx . Data [ "Err_Title" ] = true
ctx . RenderWithErr ( ctx . Tr ( "repo.wiki.reserved_page" , wikiName ) , tplWikiNew , & form )
} else if models . IsErrWikiAlreadyExist ( err ) {
2015-11-27 09:50:38 +03:00
ctx . Data [ "Err_Title" ] = true
2016-11-21 13:03:42 +03:00
ctx . RenderWithErr ( ctx . Tr ( "repo.wiki.page_already_exists" ) , tplWikiNew , & form )
2015-11-27 09:50:38 +03:00
} else {
2018-01-11 00:34:17 +03:00
ctx . ServerError ( "AddWikiPage" , err )
2015-11-27 09:50:38 +03:00
}
2015-11-27 01:33:45 +03:00
return
}
2020-01-07 21:27:36 +03:00
ctx . Redirect ( ctx . Repo . RepoLink + "/wiki/" + wiki_service . NameToSubURL ( wikiName ) )
2015-11-27 01:33:45 +03:00
}
2016-11-21 13:03:42 +03:00
// EditWiki render wiki modify page
2016-03-11 19:56:52 +03:00
func EditWiki ( ctx * context . Context ) {
2015-11-27 09:50:38 +03:00
ctx . Data [ "PageIsWiki" ] = true
ctx . Data [ "PageIsWikiEdit" ] = true
ctx . Data [ "RequireSimpleMDE" ] = true
if ! ctx . Repo . Repository . HasWiki ( ) {
ctx . Redirect ( ctx . Repo . RepoLink + "/wiki" )
return
}
2019-07-08 11:20:22 +03:00
renderEditPage ( ctx )
2015-11-27 09:50:38 +03:00
if ctx . Written ( ) {
return
}
2016-11-21 13:03:42 +03:00
ctx . HTML ( 200 , tplWikiNew )
2015-11-27 09:50:38 +03:00
}
2017-11-28 12:43:51 +03:00
// EditWikiPost response for wiki modify request
2016-03-11 19:56:52 +03:00
func EditWikiPost ( ctx * context . Context , form auth . NewWikiForm ) {
2015-11-27 09:50:38 +03:00
ctx . Data [ "Title" ] = ctx . Tr ( "repo.wiki.new_page" )
ctx . Data [ "PageIsWiki" ] = true
ctx . Data [ "RequireSimpleMDE" ] = true
if ctx . HasError ( ) {
2016-11-21 13:03:42 +03:00
ctx . HTML ( 200 , tplWikiNew )
2015-11-27 09:50:38 +03:00
return
}
2020-01-07 21:27:36 +03:00
oldWikiName := wiki_service . NormalizeWikiName ( ctx . Params ( ":page" ) )
newWikiName := wiki_service . NormalizeWikiName ( form . Title )
2017-01-21 15:50:51 +03:00
2020-05-22 16:14:02 +03:00
if len ( form . Message ) == 0 {
form . Message = ctx . Tr ( "repo.editor.update" , form . Title )
}
2020-01-07 21:27:36 +03:00
if err := wiki_service . EditWikiPage ( ctx . User , ctx . Repo . Repository , oldWikiName , newWikiName , form . Content , form . Message ) ; err != nil {
2018-01-11 00:34:17 +03:00
ctx . ServerError ( "EditWikiPage" , err )
2015-11-27 09:50:38 +03:00
return
}
2020-01-07 21:27:36 +03:00
ctx . Redirect ( ctx . Repo . RepoLink + "/wiki/" + wiki_service . NameToSubURL ( newWikiName ) )
2015-11-26 04:10:25 +03:00
}
2016-03-04 01:06:50 +03:00
2016-11-21 13:03:42 +03:00
// DeleteWikiPagePost delete wiki page
2016-03-11 19:56:52 +03:00
func DeleteWikiPagePost ( ctx * context . Context ) {
2020-01-07 21:27:36 +03:00
wikiName := wiki_service . NormalizeWikiName ( ctx . Params ( ":page" ) )
2017-11-28 12:43:51 +03:00
if len ( wikiName ) == 0 {
wikiName = "Home"
2016-03-04 01:06:50 +03:00
}
2020-01-07 21:27:36 +03:00
if err := wiki_service . DeleteWikiPage ( ctx . User , ctx . Repo . Repository , wikiName ) ; err != nil {
2018-01-11 00:34:17 +03:00
ctx . ServerError ( "DeleteWikiPage" , err )
2016-03-04 01:06:50 +03:00
return
}
ctx . JSON ( 200 , map [ string ] interface { } {
"redirect" : ctx . Repo . RepoLink + "/wiki/" ,
} )
}