summaryrefslogtreecommitdiffstats
path: root/routers/web/repo
diff options
context:
space:
mode:
authorLunny Xiao <xiaolunwen@gmail.com>2022-04-27 04:31:15 +0800
committerGitHub <noreply@github.com>2022-04-26 16:31:15 -0400
commitd71df01077fbd9366e38150e0b037008c3f808de (patch)
tree1dd4295037134e54d9a5cefa386ae325e6db6ba1 /routers/web/repo
parente4274f640ccf63b26adf409c9bc14897610fb81a (diff)
downloadgitea-d71df01077fbd9366e38150e0b037008c3f808de.tar.gz
gitea-d71df01077fbd9366e38150e0b037008c3f808de.zip
Refactor readme file renderer (#19502)
* Refactor readme file renderer * improve
Diffstat (limited to 'routers/web/repo')
-rw-r--r--routers/web/repo/view.go237
1 files changed, 125 insertions, 112 deletions
diff --git a/routers/web/repo/view.go b/routers/web/repo/view.go
index 0faa01d573..168927d101 100644
--- a/routers/web/repo/view.go
+++ b/routers/web/repo/view.go
@@ -146,6 +146,21 @@ func renderDirectory(ctx *context.Context, treeLink string) {
ctx.Data["Title"] = ctx.Tr("repo.file.title", ctx.Repo.Repository.Name+"/"+path.Base(ctx.Repo.TreePath), ctx.Repo.RefName)
}
+ // Check permission to add or upload new file.
+ if ctx.Repo.CanWrite(unit_model.TypeCode) && ctx.Repo.IsViewBranch {
+ ctx.Data["CanAddFile"] = !ctx.Repo.Repository.IsArchived
+ ctx.Data["CanUploadFile"] = setting.Repository.Upload.Enabled && !ctx.Repo.Repository.IsArchived
+ }
+
+ readmeFile, readmeTreelink := findReadmeFile(ctx, entries, treeLink)
+ if ctx.Written() || readmeFile == nil {
+ return
+ }
+
+ renderReadmeFile(ctx, readmeFile, readmeTreelink)
+}
+
+func findReadmeFile(ctx *context.Context, entries git.Entries, treeLink string) (*namedBlob, string) {
// 3 for the extensions in exts[] in order
// the last one is for a readme that doesn't
// strictly match an extension
@@ -183,7 +198,7 @@ func renderDirectory(ctx *context.Context, treeLink string) {
target, err = entry.FollowLinks()
if err != nil && !git.IsErrBadLink(err) {
ctx.ServerError("FollowLinks", err)
- return
+ return nil, ""
}
}
log.Debug("%t", target == nil)
@@ -205,7 +220,7 @@ func renderDirectory(ctx *context.Context, treeLink string) {
entry, err = entry.FollowLinks()
if err != nil && !git.IsErrBadLink(err) {
ctx.ServerError("FollowLinks", err)
- return
+ return nil, ""
}
}
if entry != nil && (entry.IsExecutable() || entry.IsRegular()) {
@@ -236,7 +251,7 @@ func renderDirectory(ctx *context.Context, treeLink string) {
readmeFile, err = getReadmeFileFromPath(ctx.Repo.Commit, entry.GetSubJumpablePathName())
if err != nil {
ctx.ServerError("getReadmeFileFromPath", err)
- return
+ return nil, ""
}
if readmeFile != nil {
readmeFile.name = entry.Name() + "/" + readmeFile.name
@@ -245,129 +260,127 @@ func renderDirectory(ctx *context.Context, treeLink string) {
}
}
}
+ return readmeFile, readmeTreelink
+}
- if readmeFile != nil {
- ctx.Data["RawFileLink"] = ""
- ctx.Data["ReadmeInList"] = true
- ctx.Data["ReadmeExist"] = true
- ctx.Data["FileIsSymlink"] = readmeFile.isSymlink
+func renderReadmeFile(ctx *context.Context, readmeFile *namedBlob, readmeTreelink string) {
+ ctx.Data["RawFileLink"] = ""
+ ctx.Data["ReadmeInList"] = true
+ ctx.Data["ReadmeExist"] = true
+ ctx.Data["FileIsSymlink"] = readmeFile.isSymlink
- dataRc, err := readmeFile.blob.DataAsync()
- if err != nil {
- ctx.ServerError("Data", err)
- return
- }
- defer dataRc.Close()
-
- buf := make([]byte, 1024)
- n, _ := util.ReadAtMost(dataRc, buf)
- buf = buf[:n]
-
- st := typesniffer.DetectContentType(buf)
- isTextFile := st.IsText()
-
- ctx.Data["FileIsText"] = isTextFile
- ctx.Data["FileName"] = readmeFile.name
- fileSize := int64(0)
- isLFSFile := false
- ctx.Data["IsLFSFile"] = false
-
- // FIXME: what happens when README file is an image?
- if isTextFile && setting.LFS.StartServer {
- pointer, _ := lfs.ReadPointerFromBuffer(buf)
- if pointer.IsValid() {
- meta, err := models.GetLFSMetaObjectByOid(ctx.Repo.Repository.ID, pointer.Oid)
- if err != nil && err != models.ErrLFSObjectNotExist {
- ctx.ServerError("GetLFSMetaObject", err)
- return
- }
- if meta != nil {
- ctx.Data["IsLFSFile"] = true
- isLFSFile = true
+ dataRc, err := readmeFile.blob.DataAsync()
+ if err != nil {
+ ctx.ServerError("Data", err)
+ return
+ }
+ defer dataRc.Close()
- // OK read the lfs object
- var err error
- dataRc, err = lfs.ReadMetaObject(pointer)
- if err != nil {
- ctx.ServerError("ReadMetaObject", err)
- return
- }
- defer dataRc.Close()
+ buf := make([]byte, 1024)
+ n, _ := util.ReadAtMost(dataRc, buf)
+ buf = buf[:n]
- buf = make([]byte, 1024)
- n, err = util.ReadAtMost(dataRc, buf)
- if err != nil {
- ctx.ServerError("Data", err)
- return
- }
- buf = buf[:n]
+ st := typesniffer.DetectContentType(buf)
+ isTextFile := st.IsText()
- st = typesniffer.DetectContentType(buf)
- isTextFile = st.IsText()
- ctx.Data["IsTextFile"] = isTextFile
+ ctx.Data["FileIsText"] = isTextFile
+ ctx.Data["FileName"] = readmeFile.name
+ fileSize := int64(0)
+ isLFSFile := false
+ ctx.Data["IsLFSFile"] = false
- fileSize = meta.Size
- ctx.Data["FileSize"] = meta.Size
- filenameBase64 := base64.RawURLEncoding.EncodeToString([]byte(readmeFile.name))
- ctx.Data["RawFileLink"] = fmt.Sprintf("%s.git/info/lfs/objects/%s/%s", ctx.Repo.Repository.HTMLURL(), url.PathEscape(meta.Oid), url.PathEscape(filenameBase64))
- }
+ // FIXME: what happens when README file is an image?
+ if isTextFile && setting.LFS.StartServer {
+ pointer, _ := lfs.ReadPointerFromBuffer(buf)
+ if pointer.IsValid() {
+ meta, err := models.GetLFSMetaObjectByOid(ctx.Repo.Repository.ID, pointer.Oid)
+ if err != nil && err != models.ErrLFSObjectNotExist {
+ ctx.ServerError("GetLFSMetaObject", err)
+ return
}
- }
-
- if !isLFSFile {
- fileSize = readmeFile.blob.Size()
- }
+ if meta != nil {
+ ctx.Data["IsLFSFile"] = true
+ isLFSFile = true
- if isTextFile {
- if fileSize >= setting.UI.MaxDisplayFileSize {
- // Pretend that this is a normal text file to display 'This file is too large to be shown'
- ctx.Data["IsFileTooLarge"] = true
- ctx.Data["IsTextFile"] = true
- ctx.Data["FileSize"] = fileSize
- } else {
- rd := charset.ToUTF8WithFallbackReader(io.MultiReader(bytes.NewReader(buf), dataRc))
-
- if markupType := markup.Type(readmeFile.name); markupType != "" {
- ctx.Data["IsMarkup"] = true
- ctx.Data["MarkupType"] = string(markupType)
- var result strings.Builder
- err := markup.Render(&markup.RenderContext{
- Ctx: ctx,
- Filename: readmeFile.name,
- URLPrefix: readmeTreelink,
- Metas: ctx.Repo.Repository.ComposeDocumentMetas(),
- GitRepo: ctx.Repo.GitRepo,
- }, rd, &result)
- if err != nil {
- log.Error("Render failed: %v then fallback", err)
- buf := &bytes.Buffer{}
- ctx.Data["EscapeStatus"], _ = charset.EscapeControlReader(rd, buf)
- ctx.Data["FileContent"] = strings.ReplaceAll(
- gotemplate.HTMLEscapeString(buf.String()), "\n", `<br>`,
- )
- } else {
- ctx.Data["EscapeStatus"], ctx.Data["FileContent"] = charset.EscapeControlString(result.String())
- }
- } else {
- ctx.Data["IsRenderedHTML"] = true
- buf := &bytes.Buffer{}
- ctx.Data["EscapeStatus"], err = charset.EscapeControlReader(rd, buf)
- if err != nil {
- log.Error("Read failed: %v", err)
- }
+ // OK read the lfs object
+ var err error
+ dataRc, err = lfs.ReadMetaObject(pointer)
+ if err != nil {
+ ctx.ServerError("ReadMetaObject", err)
+ return
+ }
+ defer dataRc.Close()
- ctx.Data["FileContent"] = strings.ReplaceAll(
- gotemplate.HTMLEscapeString(buf.String()), "\n", `<br>`,
- )
+ buf = make([]byte, 1024)
+ n, err = util.ReadAtMost(dataRc, buf)
+ if err != nil {
+ ctx.ServerError("Data", err)
+ return
}
+ buf = buf[:n]
+
+ st = typesniffer.DetectContentType(buf)
+ isTextFile = st.IsText()
+ ctx.Data["IsTextFile"] = isTextFile
+
+ fileSize = meta.Size
+ ctx.Data["FileSize"] = meta.Size
+ filenameBase64 := base64.RawURLEncoding.EncodeToString([]byte(readmeFile.name))
+ ctx.Data["RawFileLink"] = fmt.Sprintf("%s.git/info/lfs/objects/%s/%s", ctx.Repo.Repository.HTMLURL(), url.PathEscape(meta.Oid), url.PathEscape(filenameBase64))
}
}
}
- // Check permission to add or upload new file.
- if ctx.Repo.CanWrite(unit_model.TypeCode) && ctx.Repo.IsViewBranch {
- ctx.Data["CanAddFile"] = !ctx.Repo.Repository.IsArchived
- ctx.Data["CanUploadFile"] = setting.Repository.Upload.Enabled && !ctx.Repo.Repository.IsArchived
+ if !isTextFile {
+ return
+ }
+
+ if !isLFSFile {
+ fileSize = readmeFile.blob.Size()
+ }
+
+ if fileSize >= setting.UI.MaxDisplayFileSize {
+ // Pretend that this is a normal text file to display 'This file is too large to be shown'
+ ctx.Data["IsFileTooLarge"] = true
+ ctx.Data["IsTextFile"] = true
+ ctx.Data["FileSize"] = fileSize
+ return
+ }
+
+ rd := charset.ToUTF8WithFallbackReader(io.MultiReader(bytes.NewReader(buf), dataRc))
+
+ if markupType := markup.Type(readmeFile.name); markupType != "" {
+ ctx.Data["IsMarkup"] = true
+ ctx.Data["MarkupType"] = string(markupType)
+ var result strings.Builder
+ err := markup.Render(&markup.RenderContext{
+ Ctx: ctx,
+ Filename: readmeFile.name,
+ URLPrefix: readmeTreelink,
+ Metas: ctx.Repo.Repository.ComposeDocumentMetas(),
+ GitRepo: ctx.Repo.GitRepo,
+ }, rd, &result)
+ if err != nil {
+ log.Error("Render failed: %v then fallback", err)
+ buf := &bytes.Buffer{}
+ ctx.Data["EscapeStatus"], _ = charset.EscapeControlReader(rd, buf)
+ ctx.Data["FileContent"] = strings.ReplaceAll(
+ gotemplate.HTMLEscapeString(buf.String()), "\n", `<br>`,
+ )
+ } else {
+ ctx.Data["EscapeStatus"], ctx.Data["FileContent"] = charset.EscapeControlString(result.String())
+ }
+ } else {
+ ctx.Data["IsRenderedHTML"] = true
+ buf := &bytes.Buffer{}
+ ctx.Data["EscapeStatus"], err = charset.EscapeControlReader(rd, buf)
+ if err != nil {
+ log.Error("Read failed: %v", err)
+ }
+
+ ctx.Data["FileContent"] = strings.ReplaceAll(
+ gotemplate.HTMLEscapeString(buf.String()), "\n", `<br>`,
+ )
}
}