Add support for 3D/CAD file formats preview (#34794)

Fix #34775 

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
Kerwin Bryant
2025-06-30 16:12:25 +08:00
committed by GitHub
parent f74a13610d
commit 176962c03e
29 changed files with 627 additions and 409 deletions

View File

@@ -59,60 +59,63 @@ const (
)
type fileInfo struct {
isTextFile bool
isLFSFile bool
fileSize int64
lfsMeta *lfs.Pointer
st typesniffer.SniffedType
fileSize int64
lfsMeta *lfs.Pointer
st typesniffer.SniffedType
}
func getFileReader(ctx gocontext.Context, repoID int64, blob *git.Blob) ([]byte, io.ReadCloser, *fileInfo, error) {
dataRc, err := blob.DataAsync()
func (fi *fileInfo) isLFSFile() bool {
return fi.lfsMeta != nil && fi.lfsMeta.Oid != ""
}
func getFileReader(ctx gocontext.Context, repoID int64, blob *git.Blob) (buf []byte, dataRc io.ReadCloser, fi *fileInfo, err error) {
dataRc, err = blob.DataAsync()
if err != nil {
return nil, nil, nil, err
}
buf := make([]byte, 1024)
const prefetchSize = lfs.MetaFileMaxSize
buf = make([]byte, prefetchSize)
n, _ := util.ReadAtMost(dataRc, buf)
buf = buf[:n]
st := typesniffer.DetectContentType(buf)
isTextFile := st.IsText()
fi = &fileInfo{fileSize: blob.Size(), st: typesniffer.DetectContentType(buf)}
// FIXME: what happens when README file is an image?
if !isTextFile || !setting.LFS.StartServer {
return buf, dataRc, &fileInfo{isTextFile, false, blob.Size(), nil, st}, nil
if !fi.st.IsText() || !setting.LFS.StartServer {
return buf, dataRc, fi, nil
}
pointer, _ := lfs.ReadPointerFromBuffer(buf)
if !pointer.IsValid() { // fallback to plain file
return buf, dataRc, &fileInfo{isTextFile, false, blob.Size(), nil, st}, nil
if !pointer.IsValid() { // fallback to a plain file
return buf, dataRc, fi, nil
}
meta, err := git_model.GetLFSMetaObjectByOid(ctx, repoID, pointer.Oid)
if err != nil { // fallback to plain file
if err != nil { // fallback to a plain file
log.Warn("Unable to access LFS pointer %s in repo %d: %v", pointer.Oid, repoID, err)
return buf, dataRc, &fileInfo{isTextFile, false, blob.Size(), nil, st}, nil
return buf, dataRc, fi, nil
}
dataRc.Close()
// close the old dataRc and open the real LFS target
_ = dataRc.Close()
dataRc, err = lfs.ReadMetaObject(pointer)
if err != nil {
return nil, nil, nil, err
}
buf = make([]byte, 1024)
buf = make([]byte, prefetchSize)
n, err = util.ReadAtMost(dataRc, buf)
if err != nil {
dataRc.Close()
return nil, nil, nil, err
_ = dataRc.Close()
return nil, nil, fi, err
}
buf = buf[:n]
st = typesniffer.DetectContentType(buf)
return buf, dataRc, &fileInfo{st.IsText(), true, meta.Size, &meta.Pointer, st}, nil
fi.st = typesniffer.DetectContentType(buf)
fi.fileSize = blob.Size()
fi.lfsMeta = &meta.Pointer
return buf, dataRc, fi, nil
}
func loadLatestCommitData(ctx *context.Context, latestCommit *git.Commit) bool {