diff --git a/api/graphql/resolvers/user.go b/api/graphql/resolvers/user.go index cd0cbeeb..a48bbb83 100644 --- a/api/graphql/resolvers/user.go +++ b/api/graphql/resolvers/user.go @@ -321,7 +321,7 @@ func (r *mutationResolver) UserRemoveRootAlbum(ctx context.Context, userID int, var deletedAlbumIDs []int = nil - err := r.Database.Transaction(func(tx *gorm.DB) error { + transactionError := r.Database.Transaction(func(tx *gorm.DB) error { if err := tx.Raw("DELETE FROM user_albums WHERE user_id = ? AND album_id = ?", userID, albumID).Error; err != nil { return err } @@ -346,12 +346,12 @@ func (r *mutationResolver) UserRemoveRootAlbum(ctx context.Context, userID int, } // Cleanup if no user owns the album anymore - var count int - if err := tx.Raw("SELECT COUNT(user_id) FROM user_albums WHERE album_id = ?", albumID).Scan(&count).Error; err != nil { + var userAlbumCount int + if err := tx.Raw("SELECT COUNT(user_id) FROM user_albums WHERE album_id = ?", albumID).Scan(&userAlbumCount).Error; err != nil { return err } - if count == 0 { + if userAlbumCount == 0 { deletedAlbumIDs = append(childAlbumIDs, albumID) childAlbumIDs = nil @@ -360,17 +360,13 @@ func (r *mutationResolver) UserRemoveRootAlbum(ctx context.Context, userID int, deletedAlbumIDs = nil return err } - - if err := face_detection.GlobalFaceDetector.ReloadFacesFromDatabase(tx); err != nil { - return err - } } return nil }) - if err != nil { - return nil, err + if transactionError != nil { + return nil, transactionError } if deletedAlbumIDs != nil { @@ -382,6 +378,11 @@ func (r *mutationResolver) UserRemoveRootAlbum(ctx context.Context, userID int, return nil, err } } + + // Reload faces as media might have been deleted + if err := face_detection.GlobalFaceDetector.ReloadFacesFromDatabase(r.Database); err != nil { + return nil, err + } } return &album, nil diff --git a/api/scanner/face_detection/face_detector.go b/api/scanner/face_detection/face_detector.go index 9fdce00f..09e44a1c 100644 --- a/api/scanner/face_detection/face_detector.go +++ b/api/scanner/face_detection/face_detector.go @@ -84,8 +84,8 @@ func (fd *FaceDetector) ReloadFacesFromDatabase(db *gorm.DB) error { } // DetectFaces finds the faces in the given image and saves them to the database -func (fd *FaceDetector) DetectFaces(tx *gorm.DB, media *models.Media) error { - if err := tx.Model(media).Preload("MediaURL").First(&media).Error; err != nil { +func (fd *FaceDetector) DetectFaces(db *gorm.DB, media *models.Media) error { + if err := db.Model(media).Preload("MediaURL").First(&media).Error; err != nil { return err } @@ -116,7 +116,7 @@ func (fd *FaceDetector) DetectFaces(tx *gorm.DB, media *models.Media) error { } for _, face := range faces { - fd.classifyFace(tx, &face, media, thumbnailPath) + fd.classifyFace(db, &face, media, thumbnailPath) } return nil @@ -126,7 +126,7 @@ func (fd *FaceDetector) classifyDescriptor(descriptor face.Descriptor) int32 { return int32(fd.rec.ClassifyThreshold(descriptor, 0.2)) } -func (fd *FaceDetector) classifyFace(tx *gorm.DB, face *face.Face, media *models.Media, imagePath string) error { +func (fd *FaceDetector) classifyFace(db *gorm.DB, face *face.Face, media *models.Media, imagePath string) error { fd.mutex.Lock() defer fd.mutex.Unlock() @@ -153,18 +153,18 @@ func (fd *FaceDetector) classifyFace(tx *gorm.DB, face *face.Face, media *models ImageFaces: []models.ImageFace{imageFace}, } - if err := tx.Create(&faceGroup).Error; err != nil { + if err := db.Create(&faceGroup).Error; err != nil { return err } } else { log.Println("Found match") - if err := tx.First(&faceGroup, int(match)).Error; err != nil { + if err := db.First(&faceGroup, int(match)).Error; err != nil { return err } - if err := tx.Model(&faceGroup).Association("ImageFaces").Append(&imageFace); err != nil { + if err := db.Model(&faceGroup).Association("ImageFaces").Append(&imageFace); err != nil { return err } } diff --git a/api/scanner/scanner_album.go b/api/scanner/scanner_album.go index 46861817..9e89b3a3 100644 --- a/api/scanner/scanner_album.go +++ b/api/scanner/scanner_album.go @@ -75,10 +75,11 @@ func scanAlbum(album *models.Album, cache *AlbumScannerCache, db *gorm.DB) { album_has_changes := false for count, media := range albumMedia { - // tx, err := db.Begin() + processing_was_needed := false transactionError := db.Transaction(func(tx *gorm.DB) error { - processing_was_needed, err := ProcessMedia(tx, media) + log.Printf("Process media transaction enter (%s)", media.Path) + processing_was_needed, err = ProcessMedia(tx, media) if err != nil { return errors.Wrapf(err, "failed to process photo (%s)", media.Path) } @@ -93,22 +94,23 @@ func scanAlbum(album *models.Album, cache *AlbumScannerCache, db *gorm.DB) { Content: fmt.Sprintf("Processed media at %s", media.Path), Progress: &progress, }) - - if media.Type == models.MediaTypePhoto { - go func() { - if err := face_detection.GlobalFaceDetector.DetectFaces(tx, media); err != nil { - ScannerError("Error detecting faces in image (%s): %s", media.Path, err) - } - }() - } } + log.Printf("Process media transaction exit (%s)", media.Path) return nil }) if transactionError != nil { ScannerError("Failed to begin database transaction: %s", transactionError) } + + if processing_was_needed && media.Type == models.MediaTypePhoto { + go func(media *models.Media) { + if err := face_detection.GlobalFaceDetector.DetectFaces(db, media); err != nil { + ScannerError("Error detecting faces in image (%s): %s", media.Path, err) + } + }(media) + } } cleanup_errors := CleanupMedia(db, album.ID, albumMedia)