aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLunny Xiao <xiaolunwen@gmail.com>2022-12-14 18:11:11 +0800
committerGitHub <noreply@github.com>2022-12-14 18:11:11 +0800
commit1b32ed014a61216b75d80643df53e120606ca763 (patch)
tree0e6780ec6e74291fabf3afb9a9ceb76caccaffab
parent07461e18d33c78de2d6ae028f8ddba72f971db81 (diff)
downloadgitea-1b32ed014a61216b75d80643df53e120606ca763.tar.gz
gitea-1b32ed014a61216b75d80643df53e120606ca763.zip
remove duplicated read file code (#22042)
Merge the duplicated read file code as one function in reading text file and readme file.
-rw-r--r--routers/web/repo/view.go199
1 files changed, 82 insertions, 117 deletions
diff --git a/routers/web/repo/view.go b/routers/web/repo/view.go
index fa4eb6d61f..f139a971fc 100644
--- a/routers/web/repo/view.go
+++ b/routers/web/repo/view.go
@@ -241,18 +241,19 @@ func findReadmeFile(ctx *context.Context, entries git.Entries, treeLink string)
return readmeFile, readmeTreelink
}
-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
+type fileInfo struct {
+ isTextFile bool
+ isLFSFile bool
+ fileSize int64
+ lfsMeta *lfs.Pointer
+ st typesniffer.SniffedType
+}
- dataRc, err := readmeFile.blob.DataAsync()
+func getFileReader(repoID int64, blob *git.Blob) ([]byte, io.ReadCloser, *fileInfo, error) {
+ dataRc, err := blob.DataAsync()
if err != nil {
- ctx.ServerError("Data", err)
- return
+ return nil, nil, nil, err
}
- defer dataRc.Close()
buf := make([]byte, 1024)
n, _ := util.ReadAtMost(dataRc, buf)
@@ -261,67 +262,75 @@ func renderReadmeFile(ctx *context.Context, readmeFile *namedBlob, readmeTreelin
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 := git_model.GetLFSMetaObjectByOid(ctx.Repo.Repository.ID, pointer.Oid)
- if err != nil && err != git_model.ErrLFSObjectNotExist {
- ctx.ServerError("GetLFSMetaObject", err)
- return
- }
- if meta != nil {
- ctx.Data["IsLFSFile"] = true
- isLFSFile = true
+ if !isTextFile || !setting.LFS.StartServer {
+ return buf, dataRc, &fileInfo{isTextFile, false, blob.Size(), nil, st}, nil
+ }
- // OK read the lfs object
- var err error
- dataRc, err = lfs.ReadMetaObject(pointer)
- if err != nil {
- ctx.ServerError("ReadMetaObject", err)
- return
- }
- defer dataRc.Close()
+ pointer, _ := lfs.ReadPointerFromBuffer(buf)
+ if !pointer.IsValid() { // fallback to plain file
+ return buf, dataRc, &fileInfo{isTextFile, false, blob.Size(), nil, st}, nil
+ }
- buf = make([]byte, 1024)
- n, err = util.ReadAtMost(dataRc, buf)
- if err != nil {
- ctx.ServerError("Data", err)
- return
- }
- buf = buf[:n]
+ meta, err := git_model.GetLFSMetaObjectByOid(repoID, pointer.Oid)
+ if err != git_model.ErrLFSObjectNotExist { // fallback to plain file
+ return buf, dataRc, &fileInfo{isTextFile, false, blob.Size(), nil, st}, nil
+ }
- st = typesniffer.DetectContentType(buf)
- isTextFile = st.IsText()
- ctx.Data["IsTextFile"] = isTextFile
+ dataRc.Close()
+ if err != nil {
+ return nil, nil, nil, err
+ }
- 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))
- }
- }
+ dataRc, err = lfs.ReadMetaObject(pointer)
+ if err != nil {
+ return nil, nil, nil, err
}
- if !isTextFile {
+ buf = make([]byte, 1024)
+ n, err = util.ReadAtMost(dataRc, buf)
+ if err != nil {
+ dataRc.Close()
+ return nil, nil, nil, err
+ }
+ buf = buf[:n]
+
+ st = typesniffer.DetectContentType(buf)
+
+ return buf, dataRc, &fileInfo{st.IsText(), true, meta.Size, &meta.Pointer, st}, nil
+}
+
+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
+
+ buf, dataRc, fInfo, err := getFileReader(ctx.Repo.Repository.ID, readmeFile.blob)
+ if err != nil {
+ ctx.ServerError("getFileReader", err)
return
}
+ defer dataRc.Close()
+
+ ctx.Data["FileIsText"] = fInfo.isTextFile
+ ctx.Data["FileName"] = readmeFile.name
+ ctx.Data["IsLFSFile"] = fInfo.isLFSFile
+
+ if fInfo.isLFSFile {
+ 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(fInfo.lfsMeta.Oid), url.PathEscape(filenameBase64))
+ }
- if !isLFSFile {
- fileSize = readmeFile.blob.Size()
+ if !fInfo.isTextFile {
+ return
}
- if fileSize >= setting.UI.MaxDisplayFileSize {
+ if fInfo.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
+ ctx.Data["FileSize"] = fInfo.fileSize
return
}
@@ -362,16 +371,14 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
ctx.Data["IsViewFile"] = true
ctx.Data["HideRepoInfo"] = true
blob := entry.Blob()
- dataRc, err := blob.DataAsync()
+ buf, dataRc, fInfo, err := getFileReader(ctx.Repo.Repository.ID, blob)
if err != nil {
- ctx.ServerError("DataAsync", err)
+ ctx.ServerError("getFileReader", err)
return
}
defer dataRc.Close()
ctx.Data["Title"] = ctx.Tr("repo.file.title", ctx.Repo.Repository.Name+"/"+path.Base(ctx.Repo.TreePath), ctx.Repo.RefName)
-
- fileSize := blob.Size()
ctx.Data["FileIsSymlink"] = entry.IsLink()
ctx.Data["FileName"] = blob.Name()
ctx.Data["RawFileLink"] = rawLink + "/" + util.PathEscapeSegments(ctx.Repo.TreePath)
@@ -381,69 +388,27 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
ctx.Data["FileError"] = editorconfigErr
}
- buf := make([]byte, 1024)
- n, _ := util.ReadAtMost(dataRc, buf)
- buf = buf[:n]
-
- st := typesniffer.DetectContentType(buf)
- isTextFile := st.IsText()
-
- isLFSFile := false
isDisplayingSource := ctx.FormString("display") == "source"
isDisplayingRendered := !isDisplayingSource
- // Check for LFS meta file
- if isTextFile && setting.LFS.StartServer {
- pointer, _ := lfs.ReadPointerFromBuffer(buf)
- if pointer.IsValid() {
- meta, err := git_model.GetLFSMetaObjectByOid(ctx.Repo.Repository.ID, pointer.Oid)
- if err != nil && err != git_model.ErrLFSObjectNotExist {
- ctx.ServerError("GetLFSMetaObject", err)
- return
- }
- if meta != nil {
- isLFSFile = true
-
- // 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, err = util.ReadAtMost(dataRc, buf)
- if err != nil {
- ctx.ServerError("Data", err)
- return
- }
- buf = buf[:n]
-
- st = typesniffer.DetectContentType(buf)
- isTextFile = st.IsText()
-
- fileSize = meta.Size
- ctx.Data["RawFileLink"] = ctx.Repo.RepoLink + "/media/" + ctx.Repo.BranchNameSubURL() + "/" + util.PathEscapeSegments(ctx.Repo.TreePath)
- }
- }
+ if fInfo.isLFSFile {
+ ctx.Data["RawFileLink"] = ctx.Repo.RepoLink + "/media/" + ctx.Repo.BranchNameSubURL() + "/" + util.PathEscapeSegments(ctx.Repo.TreePath)
}
- isRepresentableAsText := st.IsRepresentableAsText()
+ isRepresentableAsText := fInfo.st.IsRepresentableAsText()
if !isRepresentableAsText {
// If we can't show plain text, always try to render.
isDisplayingSource = false
isDisplayingRendered = true
}
- ctx.Data["IsLFSFile"] = isLFSFile
- ctx.Data["FileSize"] = fileSize
- ctx.Data["IsTextFile"] = isTextFile
+ ctx.Data["IsLFSFile"] = fInfo.isLFSFile
+ ctx.Data["FileSize"] = fInfo.fileSize
+ ctx.Data["IsTextFile"] = fInfo.isTextFile
ctx.Data["IsRepresentableAsText"] = isRepresentableAsText
ctx.Data["IsDisplayingSource"] = isDisplayingSource
ctx.Data["IsDisplayingRendered"] = isDisplayingRendered
- isTextSource := isTextFile || isDisplayingSource
+ isTextSource := fInfo.isTextFile || isDisplayingSource
ctx.Data["IsTextSource"] = isTextSource
if isTextSource {
ctx.Data["CanCopyContent"] = true
@@ -468,7 +433,7 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
}
// Assume file is not editable first.
- if isLFSFile {
+ if fInfo.isLFSFile {
ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.cannot_edit_lfs_files")
} else if !isRepresentableAsText {
ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.cannot_edit_non_text_files")
@@ -476,13 +441,13 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
switch {
case isRepresentableAsText:
- if st.IsSvgImage() {
+ if fInfo.st.IsSvgImage() {
ctx.Data["IsImageFile"] = true
ctx.Data["CanCopyContent"] = true
ctx.Data["HasSourceRenderedToggle"] = true
}
- if fileSize >= setting.UI.MaxDisplayFileSize {
+ if fInfo.fileSize >= setting.UI.MaxDisplayFileSize {
ctx.Data["IsFileTooLarge"] = true
break
}
@@ -589,7 +554,7 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
ctx.Data["FileContent"] = fileContent
ctx.Data["LineEscapeStatus"] = statuses
}
- if !isLFSFile {
+ if !fInfo.isLFSFile {
if ctx.Repo.CanEnableEditor(ctx.Doer) {
if lfsLock != nil && lfsLock.OwnerID != ctx.Doer.ID {
ctx.Data["CanEditFile"] = false
@@ -605,17 +570,17 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
}
}
- case st.IsPDF():
+ case fInfo.st.IsPDF():
ctx.Data["IsPDFFile"] = true
- case st.IsVideo():
+ case fInfo.st.IsVideo():
ctx.Data["IsVideoFile"] = true
- case st.IsAudio():
+ case fInfo.st.IsAudio():
ctx.Data["IsAudioFile"] = true
- case st.IsImage() && (setting.UI.SVG.Enabled || !st.IsSvgImage()):
+ case fInfo.st.IsImage() && (setting.UI.SVG.Enabled || !fInfo.st.IsSvgImage()):
ctx.Data["IsImageFile"] = true
ctx.Data["CanCopyContent"] = true
default:
- if fileSize >= setting.UI.MaxDisplayFileSize {
+ if fInfo.fileSize >= setting.UI.MaxDisplayFileSize {
ctx.Data["IsFileTooLarge"] = true
break
}