mirror of
https://github.com/stashapp/stash.git
synced 2025-12-06 08:26:00 +01:00
Handle symlink zip files (#5249)
This commit is contained in:
parent
d1c207e40b
commit
a17199ba21
7 changed files with 18 additions and 17 deletions
|
|
@ -58,13 +58,8 @@ func (f *OsFS) Open(name string) (fs.ReadDirFile, error) {
|
||||||
return os.Open(name)
|
return os.Open(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *OsFS) OpenZip(name string) (models.ZipFS, error) {
|
func (f *OsFS) OpenZip(name string, size int64) (models.ZipFS, error) {
|
||||||
info, err := f.Lstat(name)
|
return newZipFS(f, name, size)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return newZipFS(f, name, info)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *OsFS) IsPathCaseSensitive(path string) (bool, error) {
|
func (f *OsFS) IsPathCaseSensitive(path string) (bool, error) {
|
||||||
|
|
|
||||||
|
|
@ -341,7 +341,7 @@ func (s *scanJob) acceptEntry(ctx context.Context, path string, info fs.FileInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *scanJob) scanZipFile(ctx context.Context, f scanFile) error {
|
func (s *scanJob) scanZipFile(ctx context.Context, f scanFile) error {
|
||||||
zipFS, err := f.fs.OpenZip(f.Path)
|
zipFS, err := f.fs.OpenZip(f.Path, f.Size)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, errNotReaderAt) {
|
if errors.Is(err, errNotReaderAt) {
|
||||||
// can't walk the zip file
|
// can't walk the zip file
|
||||||
|
|
@ -838,7 +838,7 @@ func (s *scanJob) getFileFS(f *models.BaseFile) (models.FS, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
zipPath := f.ZipFile.Base().Path
|
zipPath := f.ZipFile.Base().Path
|
||||||
return fs.OpenZip(zipPath)
|
return fs.OpenZip(zipPath, f.Size)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *scanJob) handleRename(ctx context.Context, f models.File, fp []models.Fingerprint) (models.File, error) {
|
func (s *scanJob) handleRename(ctx context.Context, f models.File, fp []models.Fingerprint) (models.File, error) {
|
||||||
|
|
|
||||||
|
|
@ -26,11 +26,10 @@ var (
|
||||||
type zipFS struct {
|
type zipFS struct {
|
||||||
*zip.Reader
|
*zip.Reader
|
||||||
zipFileCloser io.Closer
|
zipFileCloser io.Closer
|
||||||
zipInfo fs.FileInfo
|
|
||||||
zipPath string
|
zipPath string
|
||||||
}
|
}
|
||||||
|
|
||||||
func newZipFS(fs models.FS, path string, info fs.FileInfo) (*zipFS, error) {
|
func newZipFS(fs models.FS, path string, size int64) (*zipFS, error) {
|
||||||
reader, err := fs.Open(path)
|
reader, err := fs.Open(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -42,7 +41,7 @@ func newZipFS(fs models.FS, path string, info fs.FileInfo) (*zipFS, error) {
|
||||||
return nil, errNotReaderAt
|
return nil, errNotReaderAt
|
||||||
}
|
}
|
||||||
|
|
||||||
zipReader, err := zip.NewReader(asReaderAt, info.Size())
|
zipReader, err := zip.NewReader(asReaderAt, size)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
reader.Close()
|
reader.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -89,7 +88,6 @@ func newZipFS(fs models.FS, path string, info fs.FileInfo) (*zipFS, error) {
|
||||||
return &zipFS{
|
return &zipFS{
|
||||||
Reader: zipReader,
|
Reader: zipReader,
|
||||||
zipFileCloser: reader,
|
zipFileCloser: reader,
|
||||||
zipInfo: info,
|
|
||||||
zipPath: path,
|
zipPath: path,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
@ -125,7 +123,7 @@ func (f *zipFS) Lstat(name string) (fs.FileInfo, error) {
|
||||||
return f.Stat(name)
|
return f.Stat(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *zipFS) OpenZip(name string) (models.ZipFS, error) {
|
func (f *zipFS) OpenZip(name string, size int64) (models.ZipFS, error) {
|
||||||
return nil, errZipFSOpenZip
|
return nil, errZipFSOpenZip
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ type FS interface {
|
||||||
Stat(name string) (fs.FileInfo, error)
|
Stat(name string) (fs.FileInfo, error)
|
||||||
Lstat(name string) (fs.FileInfo, error)
|
Lstat(name string) (fs.FileInfo, error)
|
||||||
Open(name string) (fs.ReadDirFile, error)
|
Open(name string) (fs.ReadDirFile, error)
|
||||||
OpenZip(name string) (ZipFS, error)
|
OpenZip(name string, size int64) (ZipFS, error)
|
||||||
IsPathCaseSensitive(path string) (bool, error)
|
IsPathCaseSensitive(path string) (bool, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,7 @@ type DirEntry struct {
|
||||||
func (e *DirEntry) info(fs FS, path string) (fs.FileInfo, error) {
|
func (e *DirEntry) info(fs FS, path string) (fs.FileInfo, error) {
|
||||||
if e.ZipFile != nil {
|
if e.ZipFile != nil {
|
||||||
zipPath := e.ZipFile.Base().Path
|
zipPath := e.ZipFile.Base().Path
|
||||||
zfs, err := fs.OpenZip(zipPath)
|
zfs, err := fs.OpenZip(zipPath, e.ZipFile.Base().Size)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -163,7 +163,7 @@ func (f *BaseFile) Base() *BaseFile {
|
||||||
func (f *BaseFile) Open(fs FS) (io.ReadCloser, error) {
|
func (f *BaseFile) Open(fs FS) (io.ReadCloser, error) {
|
||||||
if f.ZipFile != nil {
|
if f.ZipFile != nil {
|
||||||
zipPath := f.ZipFile.Base().Path
|
zipPath := f.ZipFile.Base().Path
|
||||||
zfs, err := fs.OpenZip(zipPath)
|
zfs, err := fs.OpenZip(zipPath, f.ZipFile.Base().Size)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -178,6 +178,7 @@ type fileQueryRow struct {
|
||||||
|
|
||||||
ZipBasename null.String `db:"zip_basename"`
|
ZipBasename null.String `db:"zip_basename"`
|
||||||
ZipFolderPath null.String `db:"zip_folder_path"`
|
ZipFolderPath null.String `db:"zip_folder_path"`
|
||||||
|
ZipSize null.Int `db:"zip_size"`
|
||||||
|
|
||||||
FolderPath null.String `db:"parent_folder_path"`
|
FolderPath null.String `db:"parent_folder_path"`
|
||||||
fingerprintQueryRow
|
fingerprintQueryRow
|
||||||
|
|
@ -205,6 +206,7 @@ func (r *fileQueryRow) resolve() models.File {
|
||||||
ID: *basic.ZipFileID,
|
ID: *basic.ZipFileID,
|
||||||
Path: filepath.Join(r.ZipFolderPath.String, r.ZipBasename.String),
|
Path: filepath.Join(r.ZipFolderPath.String, r.ZipBasename.String),
|
||||||
Basename: r.ZipBasename.String,
|
Basename: r.ZipBasename.String,
|
||||||
|
Size: r.ZipSize.Int64,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -461,6 +463,8 @@ func (qb *FileStore) selectDataset() *goqu.SelectDataset {
|
||||||
fingerprintTable.Col("fingerprint"),
|
fingerprintTable.Col("fingerprint"),
|
||||||
zipFileTable.Col("basename").As("zip_basename"),
|
zipFileTable.Col("basename").As("zip_basename"),
|
||||||
zipFolderTable.Col("path").As("zip_folder_path"),
|
zipFolderTable.Col("path").As("zip_folder_path"),
|
||||||
|
// size is needed to open containing zip files
|
||||||
|
zipFileTable.Col("size").As("zip_size"),
|
||||||
}
|
}
|
||||||
|
|
||||||
cols = append(cols, videoFileQueryColumns()...)
|
cols = append(cols, videoFileQueryColumns()...)
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ type folderQueryRow struct {
|
||||||
|
|
||||||
ZipBasename null.String `db:"zip_basename"`
|
ZipBasename null.String `db:"zip_basename"`
|
||||||
ZipFolderPath null.String `db:"zip_folder_path"`
|
ZipFolderPath null.String `db:"zip_folder_path"`
|
||||||
|
ZipSize null.Int `db:"zip_size"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *folderQueryRow) resolve() *models.Folder {
|
func (r *folderQueryRow) resolve() *models.Folder {
|
||||||
|
|
@ -61,6 +62,7 @@ func (r *folderQueryRow) resolve() *models.Folder {
|
||||||
ID: *ret.ZipFileID,
|
ID: *ret.ZipFileID,
|
||||||
Path: filepath.Join(r.ZipFolderPath.String, r.ZipBasename.String),
|
Path: filepath.Join(r.ZipFolderPath.String, r.ZipBasename.String),
|
||||||
Basename: r.ZipBasename.String,
|
Basename: r.ZipBasename.String,
|
||||||
|
Size: r.ZipSize.Int64,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -148,6 +150,8 @@ func (qb *FolderStore) selectDataset() *goqu.SelectDataset {
|
||||||
table.Col("updated_at"),
|
table.Col("updated_at"),
|
||||||
zipFileTable.Col("basename").As("zip_basename"),
|
zipFileTable.Col("basename").As("zip_basename"),
|
||||||
zipFolderTable.Col("path").As("zip_folder_path"),
|
zipFolderTable.Col("path").As("zip_folder_path"),
|
||||||
|
// size is needed to open containing zip files
|
||||||
|
zipFileTable.Col("size").As("zip_size"),
|
||||||
}
|
}
|
||||||
|
|
||||||
ret := dialect.From(table).Select(cols...)
|
ret := dialect.From(table).Select(cols...)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue