-
-
Notifications
You must be signed in to change notification settings - Fork 778
/
merge.go
142 lines (115 loc) · 3.84 KB
/
merge.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
package scene
import (
"context"
"errors"
"fmt"
"os"
"github.com/stashapp/stash/pkg/file"
"github.com/stashapp/stash/pkg/fsutil"
"github.com/stashapp/stash/pkg/logger"
"github.com/stashapp/stash/pkg/models"
"github.com/stashapp/stash/pkg/sliceutil/intslice"
"github.com/stashapp/stash/pkg/txn"
)
func (s *Service) Merge(ctx context.Context, sourceIDs []int, destinationID int, scenePartial models.ScenePartial) error {
// ensure source ids are unique
sourceIDs = intslice.IntAppendUniques(nil, sourceIDs)
// ensure destination is not in source list
if intslice.IntInclude(sourceIDs, destinationID) {
return errors.New("destination scene cannot be in source list")
}
dest, err := s.Repository.Find(ctx, destinationID)
if err != nil {
return fmt.Errorf("finding destination scene ID %d: %w", destinationID, err)
}
sources, err := s.Repository.FindMany(ctx, sourceIDs)
if err != nil {
return fmt.Errorf("finding source scenes: %w", err)
}
var fileIDs []file.ID
for _, src := range sources {
// TODO - delete generated files as needed
if err := src.LoadRelationships(ctx, s.Repository); err != nil {
return fmt.Errorf("loading scene relationships from %d: %w", src.ID, err)
}
for _, f := range src.Files.List() {
fileIDs = append(fileIDs, f.Base().ID)
}
if err := s.mergeSceneMarkers(ctx, dest, src); err != nil {
return err
}
}
// move files to destination scene
if len(fileIDs) > 0 {
if err := s.Repository.AssignFiles(ctx, destinationID, fileIDs); err != nil {
return fmt.Errorf("moving files to destination scene: %w", err)
}
// if scene didn't already have a primary file, then set it now
if dest.PrimaryFileID == nil {
scenePartial.PrimaryFileID = &fileIDs[0]
} else {
// don't allow changing primary file ID from the input values
scenePartial.PrimaryFileID = nil
}
}
if _, err := s.Repository.UpdatePartial(ctx, destinationID, scenePartial); err != nil {
return fmt.Errorf("updating scene: %w", err)
}
// delete old scenes
for _, srcID := range sourceIDs {
if err := s.Repository.Destroy(ctx, srcID); err != nil {
return fmt.Errorf("deleting scene %d: %w", srcID, err)
}
}
return nil
}
func (s *Service) mergeSceneMarkers(ctx context.Context, dest *models.Scene, src *models.Scene) error {
markers, err := s.MarkerRepository.FindBySceneID(ctx, src.ID)
if err != nil {
return fmt.Errorf("finding scene markers: %w", err)
}
type rename struct {
src string
dest string
}
var toRename []rename
destHash := dest.GetHash(s.Config.GetVideoFileNamingAlgorithm())
for _, m := range markers {
srcHash := src.GetHash(s.Config.GetVideoFileNamingAlgorithm())
// updated the scene id
m.SceneID.Int64 = int64(dest.ID)
if _, err := s.MarkerRepository.Update(ctx, *m); err != nil {
return fmt.Errorf("updating scene marker %d: %w", m.ID, err)
}
// move generated files to new location
toRename = append(toRename, []rename{
{
src: s.Paths.SceneMarkers.GetScreenshotPath(srcHash, int(m.Seconds)),
dest: s.Paths.SceneMarkers.GetScreenshotPath(destHash, int(m.Seconds)),
},
{
src: s.Paths.SceneMarkers.GetThumbnailPath(srcHash, int(m.Seconds)),
dest: s.Paths.SceneMarkers.GetThumbnailPath(destHash, int(m.Seconds)),
},
{
src: s.Paths.SceneMarkers.GetWebpPreviewPath(srcHash, int(m.Seconds)),
dest: s.Paths.SceneMarkers.GetWebpPreviewPath(destHash, int(m.Seconds)),
},
}...)
}
if len(toRename) > 0 {
txn.AddPostCommitHook(ctx, func(ctx context.Context) {
// rename the files if they exist
for _, e := range toRename {
srcExists, _ := fsutil.FileExists(e.src)
destExists, _ := fsutil.FileExists(e.dest)
if srcExists && !destExists {
if err := os.Rename(e.src, e.dest); err != nil {
logger.Errorf("Error renaming generated marker file from %s to %s: %v", e.src, e.dest, err)
}
}
}
})
}
return nil
}