From 602f95dd29cb89d59c54d3917c4b97ea2d8115bc Mon Sep 17 00:00:00 2001 From: WithoutPants <53250216+WithoutPants@users.noreply.github.com> Date: Thu, 7 Nov 2024 14:29:26 +1100 Subject: [PATCH] Fix video files with identical phashes being merged during scan (#5461) * Change Fingerprints.Remove to return new instead of mutate current * Match only by oshash and md5 when merging scenes during scan --- pkg/file/scan.go | 3 ++- pkg/models/fingerprint.go | 21 ++++++++++++++++++--- pkg/scene/scan.go | 6 +++++- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/pkg/file/scan.go b/pkg/file/scan.go index 3cfc4c26b..8b0ec956e 100644 --- a/pkg/file/scan.go +++ b/pkg/file/scan.go @@ -1100,7 +1100,8 @@ func (s *scanJob) removeOutdatedFingerprints(existing models.File, fp models.Fin // oshash has changed, MD5 is missing - remove MD5 from the existing fingerprints logger.Infof("Removing outdated checksum from %s", existing.Base().Path) - existing.Base().Fingerprints.Remove(models.FingerprintTypeMD5) + b := existing.Base() + b.Fingerprints = b.Fingerprints.Remove(models.FingerprintTypeMD5) } // returns a file only if it was updated diff --git a/pkg/models/fingerprint.go b/pkg/models/fingerprint.go index 0123f289d..338e99534 100644 --- a/pkg/models/fingerprint.go +++ b/pkg/models/fingerprint.go @@ -28,16 +28,31 @@ func (f *Fingerprint) Value() string { type Fingerprints []Fingerprint -func (f *Fingerprints) Remove(type_ string) { +func (f Fingerprints) Remove(type_ string) Fingerprints { var ret Fingerprints - for _, ff := range *f { + for _, ff := range f { if ff.Type != type_ { ret = append(ret, ff) } } - *f = ret + return ret +} + +func (f Fingerprints) Filter(types ...string) Fingerprints { + var ret Fingerprints + + for _, ff := range f { + for _, t := range types { + if ff.Type == t { + ret = append(ret, ff) + break + } + } + } + + return ret } // Equals returns true if the contents of this slice are equal to those in the other slice. diff --git a/pkg/scene/scan.go b/pkg/scene/scan.go index 5676f6d4f..e1038fbc3 100644 --- a/pkg/scene/scan.go +++ b/pkg/scene/scan.go @@ -16,6 +16,10 @@ import ( var ( ErrNotVideoFile = errors.New("not a video file") + + // fingerprint types to match with + // only try to match by data fingerprints, _not_ perceptual fingerprints + matchableFingerprintTypes = []string{models.FingerprintTypeOshash, models.FingerprintTypeMD5} ) type ScanCreatorUpdater interface { @@ -87,7 +91,7 @@ func (h *ScanHandler) Handle(ctx context.Context, f models.File, oldFile models. if len(existing) == 0 { // try also to match file by fingerprints - existing, err = h.CreatorUpdater.FindByFingerprints(ctx, videoFile.Fingerprints) + existing, err = h.CreatorUpdater.FindByFingerprints(ctx, videoFile.Fingerprints.Filter(matchableFingerprintTypes...)) if err != nil { return fmt.Errorf("finding existing scene by fingerprints: %w", err) }