From 3b61ff1895d07ef66c8d9cb2408cba1c2490996a Mon Sep 17 00:00:00 2001 From: zeripath Date: Thu, 21 Feb 2019 20:57:16 +0000 Subject: [PATCH] Allow display of LFS stored Readme.md on directory page (#6073) (#6099) * Fix display of >1Kb LFS text files * Make LFS stored Readme files viewable Signed-off-by: Andrew Thornton * Slight restructure Signed-off-by: Andrew Thornton * Slight restructure Signed-off-by: Andrew Thornton * catch errors and restructure LFS sections --- routers/repo/view.go | 118 +++++++++++++++++++++++++++++++++---------- 1 file changed, 90 insertions(+), 28 deletions(-) diff --git a/routers/repo/view.go b/routers/repo/view.go index da6c52724..c14537bf9 100644 --- a/routers/repo/view.go +++ b/routers/repo/view.go @@ -103,13 +103,62 @@ func renderDirectory(ctx *context.Context, treeLink string) { isTextFile := base.IsTextFile(buf) 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 { + meta := lfs.IsPointerFile(&buf) + if meta != nil { + meta, err = ctx.Repo.Repository.GetLFSMetaObjectByOid(meta.Oid) + if err != nil && err != models.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(meta) + if err != nil { + ctx.ServerError("ReadMetaObject", err) + return + } + defer dataRc.Close() + + buf = make([]byte, 1024) + n, err = dataRc.Read(buf) + if err != nil { + ctx.ServerError("Data", err) + return + } + buf = buf[:n] + + isTextFile = base.IsTextFile(buf) + 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%s.git/info/lfs/objects/%s/%s", setting.AppURL, ctx.Repo.Repository.FullName(), meta.Oid, filenameBase64) + } + } + + if !isLFSFile { + fileSize = readmeFile.Size() + } + if isTextFile { - if readmeFile.Size() >= setting.UI.MaxDisplayFileSize { + 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"] = readmeFile.Size() + ctx.Data["FileSize"] = fileSize } else { d, _ := ioutil.ReadAll(dataRc) buf = templates.ToUTF8WithFallback(append(buf, d...)) @@ -168,7 +217,8 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st ctx.Data["Title"] = ctx.Data["Title"].(string) + " - " + ctx.Repo.TreePath + " at " + ctx.Repo.BranchName - ctx.Data["FileSize"] = blob.Size() + fileSize := blob.Size() + ctx.Data["FileSize"] = fileSize ctx.Data["FileName"] = blob.Name() ctx.Data["HighlightClass"] = highlight.FileNameToHighlightClass(blob.Name()) ctx.Data["RawFileLink"] = rawLink + "/" + ctx.Repo.TreePath @@ -182,32 +232,44 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st ctx.Data["IsTextFile"] = isTextFile //Check for LFS meta file - if isTextFile { - if meta := lfs.IsPointerFile(&buf); meta != nil { - if meta, _ = ctx.Repo.Repository.GetLFSMetaObjectByOid(meta.Oid); meta != nil { - ctx.Data["IsLFSFile"] = true - isLFSFile = true - - // OK read the lfs object - dataRc, err := lfs.ReadMetaObject(meta) - if err != nil { - ctx.ServerError("ReadMetaObject", err) - return - } - defer dataRc.Close() - - buf = make([]byte, 1024) - n, _ = dataRc.Read(buf) - buf = buf[:n] - - isTextFile = base.IsTextFile(buf) - ctx.Data["IsTextFile"] = isTextFile - - ctx.Data["FileSize"] = meta.Size - filenameBase64 := base64.RawURLEncoding.EncodeToString([]byte(blob.Name())) - ctx.Data["RawFileLink"] = fmt.Sprintf("%s%s.git/info/lfs/objects/%s/%s", setting.AppURL, ctx.Repo.Repository.FullName(), meta.Oid, filenameBase64) + if isTextFile && setting.LFS.StartServer { + meta := lfs.IsPointerFile(&buf) + if meta != nil { + meta, err = ctx.Repo.Repository.GetLFSMetaObjectByOid(meta.Oid) + if err != nil && err != models.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(meta) + if err != nil { + ctx.ServerError("ReadMetaObject", err) + return + } + defer dataRc.Close() + + buf = make([]byte, 1024) + n, err = dataRc.Read(buf) + if err != nil { + ctx.ServerError("Data", err) + return + } + buf = buf[:n] + + isTextFile = base.IsTextFile(buf) + ctx.Data["IsTextFile"] = isTextFile + + fileSize = meta.Size + ctx.Data["FileSize"] = meta.Size + filenameBase64 := base64.RawURLEncoding.EncodeToString([]byte(blob.Name())) + ctx.Data["RawFileLink"] = fmt.Sprintf("%s%s.git/info/lfs/objects/%s/%s", setting.AppURL, ctx.Repo.Repository.FullName(), meta.Oid, filenameBase64) + } } // Assume file is not editable first. @@ -219,7 +281,7 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st switch { case isTextFile: - if blob.Size() >= setting.UI.MaxDisplayFileSize { + if fileSize >= setting.UI.MaxDisplayFileSize { ctx.Data["IsFileTooLarge"] = true break }