[Files Refactor] Bug fixes (#2868)

* Return error if multiple rows returned for id
* Add missing LoadFiles calls
* Show id if path is empty
This commit is contained in:
WithoutPants 2022-09-02 11:18:37 +10:00
parent 273cf0383d
commit 94d39da706
23 changed files with 93 additions and 26 deletions

View file

@ -338,10 +338,6 @@ func (r *mutationResolver) GalleryDestroy(ctx context.Context, input models.Gall
return fmt.Errorf("gallery with id %d not found", id)
}
if err := gallery.LoadFiles(ctx, qb); err != nil {
return err
}
galleries = append(galleries, gallery)
imgsDestroyed, err = r.galleryService.Destroy(ctx, gallery, fileDeleter, deleteGenerated, deleteFile)

View file

@ -58,10 +58,6 @@ func (r *mutationResolver) SubmitStashBoxSceneDraft(ctx context.Context, input S
return err
}
if err := scene.LoadStashIDs(ctx, qb); err != nil {
return err
}
filepath := manager.GetInstance().Paths.Scene.GetScreenshotPath(scene.GetHash(config.GetInstance().GetVideoFileNamingAlgorithm()))
res, err = client.SubmitSceneDraft(ctx, scene, boxes[input.StashBoxIndex].Endpoint, filepath)

View file

@ -31,7 +31,7 @@ func getGalleryFileTagger(s *models.Gallery, cache *match.Cache) tagger {
return tagger{
ID: s.ID,
Type: "gallery",
Name: s.GetTitle(),
Name: s.DisplayName(),
Path: path,
trimExt: trimExt,
cache: cache,

View file

@ -23,7 +23,7 @@ func getImageFileTagger(s *models.Image, cache *match.Cache) tagger {
return tagger{
ID: s.ID,
Type: "image",
Name: s.GetTitle(),
Name: s.DisplayName(),
Path: s.Path,
cache: cache,
}

View file

@ -23,7 +23,7 @@ func getSceneFileTagger(s *models.Scene, cache *match.Cache) tagger {
return tagger{
ID: s.ID,
Type: "scene",
Name: s.GetTitle(),
Name: s.DisplayName(),
Path: s.Path,
cache: cache,
}

View file

@ -121,11 +121,11 @@ func (t *tagger) tagScenes(ctx context.Context, paths []string, sceneReader scen
added, err := addFunc(p)
if err != nil {
return t.addError("scene", p.GetTitle(), err)
return t.addError("scene", p.DisplayName(), err)
}
if added {
t.addLog("scene", p.GetTitle())
t.addLog("scene", p.DisplayName())
}
}
@ -142,11 +142,11 @@ func (t *tagger) tagImages(ctx context.Context, paths []string, imageReader imag
added, err := addFunc(p)
if err != nil {
return t.addError("image", p.GetTitle(), err)
return t.addError("image", p.DisplayName(), err)
}
if added {
t.addLog("image", p.GetTitle())
t.addLog("image", p.DisplayName())
}
}
@ -163,11 +163,11 @@ func (t *tagger) tagGalleries(ctx context.Context, paths []string, galleryReader
added, err := addFunc(p)
if err != nil {
return t.addError("gallery", p.GetTitle(), err)
return t.addError("gallery", p.DisplayName(), err)
}
if added {
t.addLog("gallery", p.GetTitle())
t.addLog("gallery", p.DisplayName())
}
}

View file

@ -212,7 +212,7 @@ func (h *cleanHandler) deleteRelatedScenes(ctx context.Context, fileDeleter *fil
// only delete if the scene has no other files
if len(scene.Files.List()) <= 1 {
logger.Infof("Deleting scene %q since it has no other related files", scene.GetTitle())
logger.Infof("Deleting scene %q since it has no other related files", scene.DisplayName())
if err := mgr.SceneService.Destroy(ctx, scene, sceneFileDeleter, true, false); err != nil {
return err
}
@ -246,7 +246,7 @@ func (h *cleanHandler) deleteRelatedGalleries(ctx context.Context, fileID file.I
// only delete if the gallery has no other files
if len(g.Files.List()) <= 1 {
logger.Infof("Deleting gallery %q since it has no other related files", g.GetTitle())
logger.Infof("Deleting gallery %q since it has no other related files", g.DisplayName())
if err := qb.Destroy(ctx, g.ID); err != nil {
return err
}
@ -270,7 +270,7 @@ func (h *cleanHandler) deleteRelatedFolderGalleries(ctx context.Context, folderI
}
for _, g := range galleries {
logger.Infof("Deleting folder-based gallery %q since the folder no longer exists", g.GetTitle())
logger.Infof("Deleting folder-based gallery %q since the folder no longer exists", g.DisplayName())
if err := qb.Destroy(ctx, g.ID); err != nil {
return err
}
@ -303,7 +303,7 @@ func (h *cleanHandler) deleteRelatedImages(ctx context.Context, fileDeleter *fil
}
if len(i.Files.List()) <= 1 {
logger.Infof("Deleting image %q since it has no other related files", i.GetTitle())
logger.Infof("Deleting image %q since it has no other related files", i.DisplayName())
if err := mgr.ImageService.Destroy(ctx, i, imageFileDeleter, true, false); err != nil {
return err
}

View file

@ -329,7 +329,7 @@ func (t *ExportTask) populateGalleryImages(ctx context.Context, repo Repository)
for _, g := range galleries {
if err := g.LoadFiles(ctx, reader); err != nil {
logger.Errorf("[galleries] <%s> failed to fetch files for gallery: %s", g.GetTitle(), err.Error())
logger.Errorf("[galleries] <%s> failed to fetch files for gallery: %s", g.DisplayName(), err.Error())
continue
}
@ -761,7 +761,7 @@ func exportGallery(ctx context.Context, wg *sync.WaitGroup, jobChan <-chan *mode
for g := range jobChan {
if err := g.LoadFiles(ctx, repo.Gallery); err != nil {
logger.Errorf("[galleries] <%s> failed to fetch files for gallery: %s", g.GetTitle(), err.Error())
logger.Errorf("[galleries] <%s> failed to fetch files for gallery: %s", g.DisplayName(), err.Error())
continue
}

View file

@ -40,6 +40,10 @@ func (s *Service) Destroy(ctx context.Context, i *models.Gallery, fileDeleter *i
}
func (s *Service) destroyZipFileImages(ctx context.Context, i *models.Gallery, fileDeleter *image.FileDeleter, deleteGenerated, deleteFile bool) ([]*models.Image, error) {
if err := i.LoadFiles(ctx, s.Repository); err != nil {
return nil, err
}
var imgsDestroyed []*models.Image
destroyer := &file.ZipDestroyer{

View file

@ -97,7 +97,7 @@ func (h *ScanHandler) associateExisting(ctx context.Context, existing []*models.
}
if !found {
logger.Infof("Adding %s to gallery %s", f.Base().Path, i.GetTitle())
logger.Infof("Adding %s to gallery %s", f.Base().Path, i.DisplayName())
if err := h.CreatorUpdater.AddFileID(ctx, i.ID, f.Base().ID); err != nil {
return fmt.Errorf("adding file to gallery: %w", err)

View file

@ -15,6 +15,7 @@ type FinderByFile interface {
type Repository interface {
FinderByFile
Destroy(ctx context.Context, id int) error
models.FileLoader
}
type ImageFinder interface {

View file

@ -81,6 +81,10 @@ func (s *Service) destroyImage(ctx context.Context, i *models.Image, fileDeleter
// deleteFiles deletes files for the image from the database and file system, if they are not in use by other images
func (s *Service) deleteFiles(ctx context.Context, i *models.Image, fileDeleter *FileDeleter) error {
if err := i.LoadFiles(ctx, s.Repository); err != nil {
return err
}
for _, f := range i.Files.List() {
// only delete files where there is no other associated image
otherImages, err := s.Repository.FindByFileID(ctx, f.ID)

View file

@ -159,7 +159,7 @@ func (h *ScanHandler) associateExisting(ctx context.Context, existing []*models.
}
if !found {
logger.Infof("Adding %s to image %s", f.Path, i.GetTitle())
logger.Infof("Adding %s to image %s", f.Path, i.DisplayName())
// associate with folder-based gallery if applicable
if h.ScanConfig.GetCreateGalleriesFromFolders() {

View file

@ -2,6 +2,7 @@ package models
import (
"context"
"strconv"
"time"
"github.com/stashapp/stash/pkg/file"
@ -128,6 +129,20 @@ func (g Gallery) GetTitle() string {
return g.Path
}
// DisplayName returns a display name for the scene for logging purposes.
// It returns the path or title, or otherwise it returns the ID if both of these are empty.
func (g Gallery) DisplayName() string {
if g.Path != "" {
return g.Path
}
if g.Title != "" {
return g.Title
}
return strconv.Itoa(g.ID)
}
const DefaultGthumbWidth int = 640
type Galleries []*Gallery

View file

@ -4,6 +4,7 @@ import (
"context"
"errors"
"path/filepath"
"strconv"
"time"
"github.com/stashapp/stash/pkg/file"
@ -96,6 +97,16 @@ func (i Image) GetTitle() string {
return ""
}
// DisplayName returns a display name for the scene for logging purposes.
// It returns Path if not empty, otherwise it returns the ID.
func (i Image) DisplayName() string {
if i.Path != "" {
return i.Path
}
return strconv.Itoa(i.ID)
}
type ImageCreateInput struct {
*Image
FileIDs []file.ID

View file

@ -222,6 +222,16 @@ func (s Scene) GetTitle() string {
return filepath.Base(s.Path)
}
// DisplayName returns a display name for the scene for logging purposes.
// It returns Path if not empty, otherwise it returns the ID.
func (s Scene) DisplayName() string {
if s.Path != "" {
return s.Path
}
return strconv.Itoa(s.ID)
}
// GetHash returns the hash of the scene, based on the hash algorithm provided. If
// hash algorithm is MD5, then Checksum is returned. Otherwise, OSHash is returned.
func (s Scene) GetHash(hashAlgorithm HashAlgorithm) string {

View file

@ -161,6 +161,10 @@ func (s *Service) Destroy(ctx context.Context, scene *models.Scene, fileDeleter
// deleteFiles deletes files from the database and file system
func (s *Service) deleteFiles(ctx context.Context, scene *models.Scene, fileDeleter *FileDeleter) error {
if err := scene.LoadFiles(ctx, s.Repository); err != nil {
return err
}
for _, f := range scene.Files.List() {
// only delete files where there is no other associated scene
otherScenes, err := s.Repository.FindByFileID(ctx, f.ID)

View file

@ -130,7 +130,7 @@ func (h *ScanHandler) associateExisting(ctx context.Context, existing []*models.
}
if !found {
logger.Infof("Adding %s to scene %s", f.Path, s.GetTitle())
logger.Infof("Adding %s to scene %s", f.Path, s.DisplayName())
if err := h.CreatorUpdater.AddFileID(ctx, s.ID, f.ID); err != nil {
return fmt.Errorf("adding file to scene: %w", err)

View file

@ -14,6 +14,7 @@ type FinderByFile interface {
type Repository interface {
FinderByFile
Destroyer
models.VideoFileLoader
}
type Service struct {

View file

@ -806,6 +806,10 @@ func (c Client) SubmitSceneDraft(ctx context.Context, scene *models.Scene, endpo
fingerprints := []*graphql.FingerprintInput{}
// submit all file fingerprints
if err := scene.LoadFiles(ctx, r.Scene); err != nil {
return nil, err
}
for _, f := range scene.Files.List() {
duration := f.Duration
@ -888,6 +892,10 @@ func (c Client) SubmitSceneDraft(ctx context.Context, scene *models.Scene, endpo
}
}
if err := scene.LoadStashIDs(ctx, r.Scene); err != nil {
return nil, err
}
stashIDs := scene.StashIDs.List()
var stashID *string
for _, v := range stashIDs {

View file

@ -299,6 +299,7 @@ func (qb *GalleryStore) get(ctx context.Context, q *goqu.SelectDataset) (*models
func (qb *GalleryStore) getMany(ctx context.Context, q *goqu.SelectDataset) ([]*models.Gallery, error) {
const single = false
var ret []*models.Gallery
var lastID int
if err := queryFunc(ctx, q, single, func(r *sqlx.Rows) error {
var f galleryQueryRow
if err := r.StructScan(&f); err != nil {
@ -307,6 +308,11 @@ func (qb *GalleryStore) getMany(ctx context.Context, q *goqu.SelectDataset) ([]*
s := f.resolve()
if s.ID == lastID {
return fmt.Errorf("internal error: multiple rows returned for single gallery id %d", s.ID)
}
lastID = s.ID
ret = append(ret, s)
return nil
}); err != nil {

View file

@ -315,6 +315,7 @@ func (qb *ImageStore) get(ctx context.Context, q *goqu.SelectDataset) (*models.I
func (qb *ImageStore) getMany(ctx context.Context, q *goqu.SelectDataset) ([]*models.Image, error) {
const single = false
var ret []*models.Image
var lastID int
if err := queryFunc(ctx, q, single, func(r *sqlx.Rows) error {
var f imageQueryRow
if err := r.StructScan(&f); err != nil {
@ -323,6 +324,11 @@ func (qb *ImageStore) getMany(ctx context.Context, q *goqu.SelectDataset) ([]*mo
i := f.resolve()
if i.ID == lastID {
return fmt.Errorf("internal error: multiple rows returned for single image id %d", i.ID)
}
lastID = i.ID
ret = append(ret, i)
return nil
}); err != nil {

View file

@ -410,6 +410,7 @@ func (qb *SceneStore) get(ctx context.Context, q *goqu.SelectDataset) (*models.S
func (qb *SceneStore) getMany(ctx context.Context, q *goqu.SelectDataset) ([]*models.Scene, error) {
const single = false
var ret []*models.Scene
var lastID int
if err := queryFunc(ctx, q, single, func(r *sqlx.Rows) error {
var f sceneQueryRow
if err := r.StructScan(&f); err != nil {
@ -417,6 +418,10 @@ func (qb *SceneStore) getMany(ctx context.Context, q *goqu.SelectDataset) ([]*mo
}
s := f.resolve()
if s.ID == lastID {
return fmt.Errorf("internal error: multiple rows returned for single scene id %d", s.ID)
}
lastID = s.ID
ret = append(ret, s)
return nil