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
This commit is contained in:
WithoutPants 2024-11-07 14:29:26 +11:00 committed by GitHub
parent 2a454e5a1e
commit 602f95dd29
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 25 additions and 5 deletions

View File

@ -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

View File

@ -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.

View File

@ -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)
}