mirror of
https://github.com/stashapp/stash.git
synced 2025-12-18 12:54:38 +03:00
Fix zip gallery moving (#3610)
* Fix folder ZipFileID synchronization * Fix zip gallery moving
This commit is contained in:
@@ -6,6 +6,7 @@ import (
|
|||||||
"io/fs"
|
"io/fs"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -122,3 +123,46 @@ func GetOrCreateFolderHierarchy(ctx context.Context, fc FolderFinderCreator, pat
|
|||||||
|
|
||||||
return folder, nil
|
return folder, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TransferZipFolderHierarchy creates the folder hierarchy for zipFileID under newPath, and removes
|
||||||
|
// ZipFileID from folders under oldPath.
|
||||||
|
func TransferZipFolderHierarchy(ctx context.Context, folderStore FolderStore, zipFileID ID, oldPath string, newPath string) error {
|
||||||
|
zipFolders, err := folderStore.FindByZipFileID(ctx, zipFileID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, oldFolder := range zipFolders {
|
||||||
|
oldZfPath := oldFolder.Path
|
||||||
|
|
||||||
|
// sanity check - ignore folders which aren't under oldPath
|
||||||
|
if !strings.HasPrefix(oldZfPath, oldPath) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
relZfPath, err := filepath.Rel(oldPath, oldZfPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
newZfPath := filepath.Join(newPath, relZfPath)
|
||||||
|
|
||||||
|
newFolder, err := GetOrCreateFolderHierarchy(ctx, folderStore, newZfPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// add ZipFileID to new folder
|
||||||
|
newFolder.ZipFileID = &zipFileID
|
||||||
|
if err = folderStore.Update(ctx, newFolder); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove ZipFileID from old folder
|
||||||
|
oldFolder.ZipFileID = nil
|
||||||
|
if err = folderStore.Update(ctx, oldFolder); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ func (m *Mover) Move(ctx context.Context, f File, folder *Folder, basename strin
|
|||||||
return fmt.Errorf("file %s already exists", newPath)
|
return fmt.Errorf("file %s already exists", newPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := m.transferZipFolderHierarchy(ctx, fBase.ID, oldPath, newPath); err != nil {
|
if err := TransferZipFolderHierarchy(ctx, m.Folders, fBase.ID, oldPath, newPath); err != nil {
|
||||||
return fmt.Errorf("moving folder hierarchy for file %s: %w", fBase.Path, err)
|
return fmt.Errorf("moving folder hierarchy for file %s: %w", fBase.Path, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,49 +166,6 @@ func (m *Mover) CreateFolderHierarchy(path string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// transferZipFolderHierarchy creates the folder hierarchy for zipFileID under newPath, and removes
|
|
||||||
// ZipFileID from folders under oldPath.
|
|
||||||
func (m *Mover) transferZipFolderHierarchy(ctx context.Context, zipFileID ID, oldPath string, newPath string) error {
|
|
||||||
zipFolders, err := m.Folders.FindByZipFileID(ctx, zipFileID)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, oldFolder := range zipFolders {
|
|
||||||
oldZfPath := oldFolder.Path
|
|
||||||
|
|
||||||
// sanity check - ignore folders which aren't under oldPath
|
|
||||||
if !strings.HasPrefix(oldZfPath, oldPath) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
relZfPath, err := filepath.Rel(oldPath, oldZfPath)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
newZfPath := filepath.Join(newPath, relZfPath)
|
|
||||||
|
|
||||||
newFolder, err := GetOrCreateFolderHierarchy(ctx, m.Folders, newZfPath)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// add ZipFileID to new folder
|
|
||||||
newFolder.ZipFileID = &zipFileID
|
|
||||||
if err = m.Folders.Update(ctx, newFolder); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove ZipFileID from old folder
|
|
||||||
oldFolder.ZipFileID = nil
|
|
||||||
if err = m.Folders.Update(ctx, oldFolder); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Mover) moveFile(oldPath, newPath string) error {
|
func (m *Mover) moveFile(oldPath, newPath string) error {
|
||||||
if err := m.Renamer.Rename(oldPath, newPath); err != nil {
|
if err := m.Renamer.Rename(oldPath, newPath); err != nil {
|
||||||
return fmt.Errorf("renaming file %s to %s: %w", oldPath, newPath, err)
|
return fmt.Errorf("renaming file %s to %s: %w", oldPath, newPath, err)
|
||||||
|
|||||||
@@ -523,13 +523,29 @@ func (s *scanJob) onNewFolder(ctx context.Context, file scanFile) (*Folder, erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *scanJob) onExistingFolder(ctx context.Context, f scanFile, existing *Folder) (*Folder, error) {
|
func (s *scanJob) onExistingFolder(ctx context.Context, f scanFile, existing *Folder) (*Folder, error) {
|
||||||
// check if the mod time is changed
|
update := false
|
||||||
|
|
||||||
|
// update if mod time is changed
|
||||||
entryModTime := f.ModTime
|
entryModTime := f.ModTime
|
||||||
|
|
||||||
if !entryModTime.Equal(existing.ModTime) {
|
if !entryModTime.Equal(existing.ModTime) {
|
||||||
// update entry in store
|
|
||||||
existing.ModTime = entryModTime
|
existing.ModTime = entryModTime
|
||||||
|
update = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// update if zip file ID has changed
|
||||||
|
fZfID := f.ZipFileID
|
||||||
|
existingZfID := existing.ZipFileID
|
||||||
|
if fZfID != existingZfID {
|
||||||
|
if fZfID == nil {
|
||||||
|
existing.ZipFileID = nil
|
||||||
|
update = true
|
||||||
|
} else if existingZfID == nil || *fZfID != *existingZfID {
|
||||||
|
existing.ZipFileID = fZfID
|
||||||
|
update = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if update {
|
||||||
var err error
|
var err error
|
||||||
if err = s.Repository.FolderStore.Update(ctx, existing); err != nil {
|
if err = s.Repository.FolderStore.Update(ctx, existing); err != nil {
|
||||||
return nil, fmt.Errorf("updating folder %q: %w", f.Path, err)
|
return nil, fmt.Errorf("updating folder %q: %w", f.Path, err)
|
||||||
@@ -753,7 +769,14 @@ func (s *scanJob) handleRename(ctx context.Context, f File, fp []Fingerprint) (F
|
|||||||
|
|
||||||
var missing []File
|
var missing []File
|
||||||
|
|
||||||
|
fZipID := f.Base().ZipFileID
|
||||||
for _, other := range others {
|
for _, other := range others {
|
||||||
|
// if file is from a zip file, then only rename if both files are from the same zip file
|
||||||
|
otherZipID := other.Base().ZipFileID
|
||||||
|
if otherZipID != nil && (fZipID == nil || *otherZipID != *fZipID) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
// if file does not exist, then update it to the new path
|
// if file does not exist, then update it to the new path
|
||||||
fs, err := s.getFileFS(other.Base())
|
fs, err := s.getFileFS(other.Base())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -798,6 +821,12 @@ func (s *scanJob) handleRename(ctx context.Context, f File, fp []Fingerprint) (F
|
|||||||
return fmt.Errorf("updating file for rename %q: %w", fBase.Path, err)
|
return fmt.Errorf("updating file for rename %q: %w", fBase.Path, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if s.isZipFile(fBase.Basename) {
|
||||||
|
if err := TransferZipFolderHierarchy(ctx, s.Repository.FolderStore, fBase.ID, otherBase.Path, fBase.Path); err != nil {
|
||||||
|
return fmt.Errorf("moving folder hierarchy for renamed zip file %q: %w", fBase.Path, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if err := s.fireHandlers(ctx, f, other); err != nil {
|
if err := s.fireHandlers(ctx, f, other); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user