From e5b247ea8e77689bb14e5f304ada36f9326f0904 Mon Sep 17 00:00:00 2001
From: Cherrg <michael@gnehr.de>
Date: Mon, 8 Jul 2019 10:20:22 +0200
Subject: wiki - page revisions list  (#7369)

fix #7

* add wiki page revision list

* mobile improvements

* css improvements for long usernames

* split renderWikiPage into 3 functions

Signed-off-by: Michael Gnehr <michael@gnehr.de>
---
 routers/repo/wiki.go | 252 ++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 188 insertions(+), 64 deletions(-)

(limited to 'routers/repo/wiki.go')

diff --git a/routers/repo/wiki.go b/routers/repo/wiki.go
index 43149c0340..0fdf853630 100644
--- a/routers/repo/wiki.go
+++ b/routers/repo/wiki.go
@@ -23,10 +23,11 @@ import (
 )
 
 const (
-	tplWikiStart base.TplName = "repo/wiki/start"
-	tplWikiView  base.TplName = "repo/wiki/view"
-	tplWikiNew   base.TplName = "repo/wiki/new"
-	tplWikiPages base.TplName = "repo/wiki/pages"
+	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"
 )
 
 // MustEnableWiki check if wiki is enabled, if external then redirect
@@ -107,18 +108,20 @@ func wikiContentsByEntry(ctx *context.Context, entry *git.TreeEntry) []byte {
 
 // 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, bool) {
-	entry, err := findEntryForFile(commit, models.WikiNameToFilename(wikiName))
-	if err != nil {
+func wikiContentsByName(ctx *context.Context, commit *git.Commit, wikiName string) ([]byte, *git.TreeEntry, string, bool) {
+	var entry *git.TreeEntry
+	var err error
+	pageFilename := models.WikiNameToFilename(wikiName)
+	if entry, err = findEntryForFile(commit, pageFilename); err != nil {
 		ctx.ServerError("findEntryForFile", err)
-		return nil, false
+		return nil, nil, "", false
 	} else if entry == nil {
-		return nil, false
+		return nil, nil, "", true
 	}
-	return wikiContentsByEntry(ctx, entry), true
+	return wikiContentsByEntry(ctx, entry), entry, pageFilename, false
 }
 
-func renderWikiPage(ctx *context.Context, isViewPage bool) (*git.Repository, *git.TreeEntry) {
+func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
 	wikiRepo, commit, err := findWikiRepoCommit(ctx)
 	if err != nil {
 		if !git.IsErrNotExist(err) {
@@ -128,88 +131,176 @@ func renderWikiPage(ctx *context.Context, isViewPage bool) (*git.Repository, *gi
 	}
 
 	// Get page list.
-	if isViewPage {
-		entries, err := commit.ListEntries()
-		if err != nil {
-			ctx.ServerError("ListEntries", err)
-			return nil, nil
+	entries, err := commit.ListEntries()
+	if err != nil {
+		ctx.ServerError("ListEntries", err)
+		return nil, nil
+	}
+	pages := make([]PageMeta, 0, len(entries))
+	for _, entry := range entries {
+		if !entry.IsRegular() {
+			continue
 		}
-		pages := make([]PageMeta, 0, len(entries))
-		for _, entry := range entries {
-			if !entry.IsRegular() {
-				continue
-			}
-			wikiName, err := models.WikiFilenameToName(entry.Name())
-			if err != nil {
-				if models.IsErrWikiInvalidFileName(err) {
-					continue
-				}
-				ctx.ServerError("WikiFilenameToName", err)
-				return nil, nil
-			} else if wikiName == "_Sidebar" || wikiName == "_Footer" {
+		wikiName, err := models.WikiFilenameToName(entry.Name())
+		if err != nil {
+			if models.IsErrWikiInvalidFileName(err) {
 				continue
 			}
-			pages = append(pages, PageMeta{
-				Name:   wikiName,
-				SubURL: models.WikiNameToSubURL(wikiName),
-			})
+			ctx.ServerError("WikiFilenameToName", err)
+			return nil, nil
+		} else if wikiName == "_Sidebar" || wikiName == "_Footer" {
+			continue
 		}
-		ctx.Data["Pages"] = pages
+		pages = append(pages, PageMeta{
+			Name:   wikiName,
+			SubURL: models.WikiNameToSubURL(wikiName),
+		})
 	}
+	ctx.Data["Pages"] = pages
 
+	// get requested pagename
 	pageName := models.NormalizeWikiName(ctx.Params(":page"))
 	if len(pageName) == 0 {
 		pageName = "Home"
 	}
 	ctx.Data["PageURL"] = models.WikiNameToSubURL(pageName)
-
 	ctx.Data["old_title"] = pageName
 	ctx.Data["Title"] = pageName
 	ctx.Data["title"] = pageName
 	ctx.Data["RequireHighlightJS"] = true
 
-	pageFilename := models.WikiNameToFilename(pageName)
-	var entry *git.TreeEntry
-	if entry, err = findEntryForFile(commit, pageFilename); err != nil {
-		ctx.ServerError("findEntryForFile", err)
-		return nil, nil
-	} else if entry == nil {
+	//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() {
 		return nil, nil
 	}
-	data := wikiContentsByEntry(ctx, entry)
+
+	sidebarContent, _, _, _ := wikiContentsByName(ctx, commit, "_Sidebar")
 	if ctx.Written() {
 		return nil, nil
 	}
 
-	if isViewPage {
-		sidebarContent, sidebarPresent := wikiContentsByName(ctx, commit, "_Sidebar")
-		if ctx.Written() {
-			return nil, nil
-		}
+	footerContent, _, _, _ := wikiContentsByName(ctx, commit, "_Footer")
+	if ctx.Written() {
+		return nil, nil
+	}
 
-		footerContent, footerPresent := wikiContentsByName(ctx, commit, "_Footer")
-		if ctx.Written() {
-			return nil, nil
+	metas := ctx.Repo.Repository.ComposeMetas()
+	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 {
+		if !git.IsErrNotExist(err) {
+			ctx.ServerError("GetBranchCommit", err)
 		}
+		return nil, nil
+	}
+
+	// get requested pagename
+	pageName := models.NormalizeWikiName(ctx.Params(":page"))
+	if len(pageName) == 0 {
+		pageName = "Home"
+	}
+	ctx.Data["PageURL"] = models.WikiNameToSubURL(pageName)
+	ctx.Data["old_title"] = pageName
+	ctx.Data["Title"] = pageName
+	ctx.Data["title"] = pageName
+	ctx.Data["RequireHighlightJS"] = true
 
-		metas := ctx.Repo.Repository.ComposeMetas()
-		ctx.Data["content"] = markdown.RenderWiki(data, ctx.Repo.RepoLink, metas)
-		ctx.Data["sidebarPresent"] = sidebarPresent
-		ctx.Data["sidebarContent"] = markdown.RenderWiki(sidebarContent, ctx.Repo.RepoLink, metas)
-		ctx.Data["footerPresent"] = footerPresent
-		ctx.Data["footerContent"] = markdown.RenderWiki(footerContent, ctx.Repo.RepoLink, metas)
-	} else {
-		ctx.Data["content"] = string(data)
-		ctx.Data["sidebarPresent"] = false
-		ctx.Data["sidebarContent"] = ""
-		ctx.Data["footerPresent"] = false
-		ctx.Data["footerContent"] = ""
+	//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() {
+		return nil, nil
 	}
 
+	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
+	commitsHistory, err := wikiRepo.CommitsByFileAndRange("master", pageFilename, page)
+	if err != nil {
+		ctx.ServerError("CommitsByFileAndRange", err)
+		return nil, nil
+	}
+	commitsHistory = models.ValidateCommitsWithEmails(commitsHistory)
+	commitsHistory = models.ParseCommitsWithSignature(commitsHistory)
+
+	ctx.Data["Commits"] = commitsHistory
+
+	pager := context.NewPagination(int(commitsCount), git.CommitsRangeSize, page, 5)
+	pager.SetDefaultParams(ctx)
+	ctx.Data["Page"] = pager
+
 	return wikiRepo, entry
 }
 
+func renderEditPage(ctx *context.Context) {
+	_, commit, err := findWikiRepoCommit(ctx)
+	if err != nil {
+		if !git.IsErrNotExist(err) {
+			ctx.ServerError("GetBranchCommit", err)
+		}
+		return
+	}
+
+	// get requested pagename
+	pageName := models.NormalizeWikiName(ctx.Params(":page"))
+	if len(pageName) == 0 {
+		pageName = "Home"
+	}
+	ctx.Data["PageURL"] = models.WikiNameToSubURL(pageName)
+	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"] = ""
+}
+
 // Wiki renders single wiki page
 func Wiki(ctx *context.Context) {
 	ctx.Data["PageIsWiki"] = true
@@ -221,7 +312,7 @@ func Wiki(ctx *context.Context) {
 		return
 	}
 
-	wikiRepo, entry := renderWikiPage(ctx, true)
+	wikiRepo, entry := renderViewPage(ctx)
 	if ctx.Written() {
 		return
 	}
@@ -247,6 +338,39 @@ func Wiki(ctx *context.Context) {
 	ctx.HTML(200, tplWikiView)
 }
 
+// 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() {
+		return
+	}
+	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)
+}
+
 // WikiPages render wiki pages list page
 func WikiPages(ctx *context.Context) {
 	if !ctx.Repo.Repository.HasWiki() {
@@ -399,7 +523,7 @@ func EditWiki(ctx *context.Context) {
 		return
 	}
 
-	renderWikiPage(ctx, false)
+	renderEditPage(ctx)
 	if ctx.Written() {
 		return
 	}
-- 
cgit v1.2.3