remove duplicated read file code (#22042)

Merge the duplicated read file code as one function in reading text file
and readme file.
This commit is contained in:
Lunny Xiao 2022-12-14 18:11:11 +08:00 committed by GitHub
parent 07461e18d3
commit 1b32ed014a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -241,18 +241,19 @@ func findReadmeFile(ctx *context.Context, entries git.Entries, treeLink string)
return readmeFile, readmeTreelink return readmeFile, readmeTreelink
} }
func renderReadmeFile(ctx *context.Context, readmeFile *namedBlob, readmeTreelink string) { type fileInfo struct {
ctx.Data["RawFileLink"] = "" isTextFile bool
ctx.Data["ReadmeInList"] = true isLFSFile bool
ctx.Data["ReadmeExist"] = true fileSize int64
ctx.Data["FileIsSymlink"] = readmeFile.isSymlink 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 { if err != nil {
ctx.ServerError("Data", err) return nil, nil, nil, err
return
} }
defer dataRc.Close()
buf := make([]byte, 1024) buf := make([]byte, 1024)
n, _ := util.ReadAtMost(dataRc, buf) n, _ := util.ReadAtMost(dataRc, buf)
@ -261,67 +262,75 @@ func renderReadmeFile(ctx *context.Context, readmeFile *namedBlob, readmeTreelin
st := typesniffer.DetectContentType(buf) st := typesniffer.DetectContentType(buf)
isTextFile := st.IsText() 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? // FIXME: what happens when README file is an image?
if isTextFile && setting.LFS.StartServer { if !isTextFile || !setting.LFS.StartServer {
pointer, _ := lfs.ReadPointerFromBuffer(buf) return buf, dataRc, &fileInfo{isTextFile, false, blob.Size(), nil, st}, nil
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
// 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()
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))
}
}
} }
if !isTextFile { pointer, _ := lfs.ReadPointerFromBuffer(buf)
if !pointer.IsValid() { // fallback to plain file
return buf, dataRc, &fileInfo{isTextFile, false, blob.Size(), nil, st}, nil
}
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
}
dataRc.Close()
if err != nil {
return nil, nil, nil, err
}
dataRc, err = lfs.ReadMetaObject(pointer)
if err != nil {
return nil, nil, nil, err
}
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 !fInfo.isTextFile {
return return
} }
if !isLFSFile { if fInfo.fileSize >= setting.UI.MaxDisplayFileSize {
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' // Pretend that this is a normal text file to display 'This file is too large to be shown'
ctx.Data["IsFileTooLarge"] = true ctx.Data["IsFileTooLarge"] = true
ctx.Data["IsTextFile"] = true ctx.Data["IsTextFile"] = true
ctx.Data["FileSize"] = fileSize ctx.Data["FileSize"] = fInfo.fileSize
return return
} }
@ -362,16 +371,14 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
ctx.Data["IsViewFile"] = true ctx.Data["IsViewFile"] = true
ctx.Data["HideRepoInfo"] = true ctx.Data["HideRepoInfo"] = true
blob := entry.Blob() blob := entry.Blob()
dataRc, err := blob.DataAsync() buf, dataRc, fInfo, err := getFileReader(ctx.Repo.Repository.ID, blob)
if err != nil { if err != nil {
ctx.ServerError("DataAsync", err) ctx.ServerError("getFileReader", err)
return return
} }
defer dataRc.Close() defer dataRc.Close()
ctx.Data["Title"] = ctx.Tr("repo.file.title", ctx.Repo.Repository.Name+"/"+path.Base(ctx.Repo.TreePath), ctx.Repo.RefName) 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["FileIsSymlink"] = entry.IsLink()
ctx.Data["FileName"] = blob.Name() ctx.Data["FileName"] = blob.Name()
ctx.Data["RawFileLink"] = rawLink + "/" + util.PathEscapeSegments(ctx.Repo.TreePath) 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 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" isDisplayingSource := ctx.FormString("display") == "source"
isDisplayingRendered := !isDisplayingSource isDisplayingRendered := !isDisplayingSource
// Check for LFS meta file if fInfo.isLFSFile {
if isTextFile && setting.LFS.StartServer { ctx.Data["RawFileLink"] = ctx.Repo.RepoLink + "/media/" + ctx.Repo.BranchNameSubURL() + "/" + util.PathEscapeSegments(ctx.Repo.TreePath)
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)
}
}
} }
isRepresentableAsText := st.IsRepresentableAsText() isRepresentableAsText := fInfo.st.IsRepresentableAsText()
if !isRepresentableAsText { if !isRepresentableAsText {
// If we can't show plain text, always try to render. // If we can't show plain text, always try to render.
isDisplayingSource = false isDisplayingSource = false
isDisplayingRendered = true isDisplayingRendered = true
} }
ctx.Data["IsLFSFile"] = isLFSFile ctx.Data["IsLFSFile"] = fInfo.isLFSFile
ctx.Data["FileSize"] = fileSize ctx.Data["FileSize"] = fInfo.fileSize
ctx.Data["IsTextFile"] = isTextFile ctx.Data["IsTextFile"] = fInfo.isTextFile
ctx.Data["IsRepresentableAsText"] = isRepresentableAsText ctx.Data["IsRepresentableAsText"] = isRepresentableAsText
ctx.Data["IsDisplayingSource"] = isDisplayingSource ctx.Data["IsDisplayingSource"] = isDisplayingSource
ctx.Data["IsDisplayingRendered"] = isDisplayingRendered ctx.Data["IsDisplayingRendered"] = isDisplayingRendered
isTextSource := isTextFile || isDisplayingSource isTextSource := fInfo.isTextFile || isDisplayingSource
ctx.Data["IsTextSource"] = isTextSource ctx.Data["IsTextSource"] = isTextSource
if isTextSource { if isTextSource {
ctx.Data["CanCopyContent"] = true 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. // Assume file is not editable first.
if isLFSFile { if fInfo.isLFSFile {
ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.cannot_edit_lfs_files") ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.cannot_edit_lfs_files")
} else if !isRepresentableAsText { } else if !isRepresentableAsText {
ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.cannot_edit_non_text_files") 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 { switch {
case isRepresentableAsText: case isRepresentableAsText:
if st.IsSvgImage() { if fInfo.st.IsSvgImage() {
ctx.Data["IsImageFile"] = true ctx.Data["IsImageFile"] = true
ctx.Data["CanCopyContent"] = true ctx.Data["CanCopyContent"] = true
ctx.Data["HasSourceRenderedToggle"] = true ctx.Data["HasSourceRenderedToggle"] = true
} }
if fileSize >= setting.UI.MaxDisplayFileSize { if fInfo.fileSize >= setting.UI.MaxDisplayFileSize {
ctx.Data["IsFileTooLarge"] = true ctx.Data["IsFileTooLarge"] = true
break break
} }
@ -589,7 +554,7 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
ctx.Data["FileContent"] = fileContent ctx.Data["FileContent"] = fileContent
ctx.Data["LineEscapeStatus"] = statuses ctx.Data["LineEscapeStatus"] = statuses
} }
if !isLFSFile { if !fInfo.isLFSFile {
if ctx.Repo.CanEnableEditor(ctx.Doer) { if ctx.Repo.CanEnableEditor(ctx.Doer) {
if lfsLock != nil && lfsLock.OwnerID != ctx.Doer.ID { if lfsLock != nil && lfsLock.OwnerID != ctx.Doer.ID {
ctx.Data["CanEditFile"] = false 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 ctx.Data["IsPDFFile"] = true
case st.IsVideo(): case fInfo.st.IsVideo():
ctx.Data["IsVideoFile"] = true ctx.Data["IsVideoFile"] = true
case st.IsAudio(): case fInfo.st.IsAudio():
ctx.Data["IsAudioFile"] = true 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["IsImageFile"] = true
ctx.Data["CanCopyContent"] = true ctx.Data["CanCopyContent"] = true
default: default:
if fileSize >= setting.UI.MaxDisplayFileSize { if fInfo.fileSize >= setting.UI.MaxDisplayFileSize {
ctx.Data["IsFileTooLarge"] = true ctx.Data["IsFileTooLarge"] = true
break break
} }