mirror of
https://github.com/stashapp/stash.git
synced 2025-12-17 20:34:37 +03:00
Add image-count sorting, and image deletion on gallery deletion (#853)
This commit is contained in:
@@ -411,10 +411,13 @@ func adjustGalleryTagIDs(tx *sqlx.Tx, galleryID int, ids models.BulkUpdateIds) (
|
|||||||
|
|
||||||
func (r *mutationResolver) GalleryDestroy(ctx context.Context, input models.GalleryDestroyInput) (bool, error) {
|
func (r *mutationResolver) GalleryDestroy(ctx context.Context, input models.GalleryDestroyInput) (bool, error) {
|
||||||
qb := models.NewGalleryQueryBuilder()
|
qb := models.NewGalleryQueryBuilder()
|
||||||
|
iqb := models.NewImageQueryBuilder()
|
||||||
tx := database.DB.MustBeginTx(ctx, nil)
|
tx := database.DB.MustBeginTx(ctx, nil)
|
||||||
|
|
||||||
var galleries []*models.Gallery
|
var galleries []*models.Gallery
|
||||||
var imgsToPostProcess []*models.Image
|
var imgsToPostProcess []*models.Image
|
||||||
|
var imgsToDelete []*models.Image
|
||||||
|
|
||||||
for _, id := range input.Ids {
|
for _, id := range input.Ids {
|
||||||
galleryID, _ := strconv.Atoi(id)
|
galleryID, _ := strconv.Atoi(id)
|
||||||
|
|
||||||
@@ -430,8 +433,7 @@ func (r *mutationResolver) GalleryDestroy(ctx context.Context, input models.Gall
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if this is a zip-based gallery, delete the images as well
|
// if this is a zip-based gallery, delete the images as well
|
||||||
if gallery.Path.Valid {
|
if gallery.Zip {
|
||||||
iqb := models.NewImageQueryBuilder()
|
|
||||||
imgs, err := iqb.FindByGalleryID(galleryID)
|
imgs, err := iqb.FindByGalleryID(galleryID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
@@ -439,7 +441,7 @@ func (r *mutationResolver) GalleryDestroy(ctx context.Context, input models.Gall
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, img := range imgs {
|
for _, img := range imgs {
|
||||||
err = qb.Destroy(img.ID, tx)
|
err = iqb.Destroy(img.ID, tx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return false, err
|
return false, err
|
||||||
@@ -447,6 +449,32 @@ func (r *mutationResolver) GalleryDestroy(ctx context.Context, input models.Gall
|
|||||||
|
|
||||||
imgsToPostProcess = append(imgsToPostProcess, img)
|
imgsToPostProcess = append(imgsToPostProcess, img)
|
||||||
}
|
}
|
||||||
|
} else if input.DeleteFile != nil && *input.DeleteFile {
|
||||||
|
// Delete image if it is only attached to this gallery
|
||||||
|
imgs, err := iqb.FindByGalleryID(galleryID)
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, img := range imgs {
|
||||||
|
imgGalleries, err := qb.FindByImageID(img.ID, tx)
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(imgGalleries) == 0 {
|
||||||
|
err = iqb.Destroy(img.ID, tx)
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
imgsToDelete = append(imgsToDelete, img)
|
||||||
|
imgsToPostProcess = append(imgsToPostProcess, img)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -460,6 +488,10 @@ func (r *mutationResolver) GalleryDestroy(ctx context.Context, input models.Gall
|
|||||||
for _, gallery := range galleries {
|
for _, gallery := range galleries {
|
||||||
manager.DeleteGalleryFile(gallery)
|
manager.DeleteGalleryFile(gallery)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, img := range imgsToDelete {
|
||||||
|
manager.DeleteImageFile(img)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if delete generated is true, then delete the generated files
|
// if delete generated is true, then delete the generated files
|
||||||
|
|||||||
@@ -181,6 +181,8 @@ func (qb *GalleryQueryBuilder) Query(galleryFilter *GalleryFilterType, findFilte
|
|||||||
left join performers_galleries as performers_join on performers_join.gallery_id = galleries.id
|
left join performers_galleries as performers_join on performers_join.gallery_id = galleries.id
|
||||||
left join studios as studio on studio.id = galleries.studio_id
|
left join studios as studio on studio.id = galleries.studio_id
|
||||||
left join galleries_tags as tags_join on tags_join.gallery_id = galleries.id
|
left join galleries_tags as tags_join on tags_join.gallery_id = galleries.id
|
||||||
|
left join galleries_images as images_join on images_join.gallery_id = galleries.id
|
||||||
|
left join images on images_join.image_id = images.id
|
||||||
`
|
`
|
||||||
|
|
||||||
if q := findFilter.Q; q != nil && *q != "" {
|
if q := findFilter.Q; q != nil && *q != "" {
|
||||||
|
|||||||
@@ -76,11 +76,13 @@ export const DeleteGalleriesDialog: React.FC<IDeleteGalleryDialogProps> = (
|
|||||||
</p>
|
</p>
|
||||||
<Form>
|
<Form>
|
||||||
<Form.Check
|
<Form.Check
|
||||||
|
id="delete-file"
|
||||||
checked={deleteFile}
|
checked={deleteFile}
|
||||||
label="Delete zip file (if applicable)"
|
label="Delete zip file and any images not attached to any other gallery."
|
||||||
onChange={() => setDeleteFile(!deleteFile)}
|
onChange={() => setDeleteFile(!deleteFile)}
|
||||||
/>
|
/>
|
||||||
<Form.Check
|
<Form.Check
|
||||||
|
id="delete-generated"
|
||||||
checked={deleteGenerated}
|
checked={deleteGenerated}
|
||||||
label="Delete generated supporting files"
|
label="Delete generated supporting files"
|
||||||
onChange={() => setDeleteGenerated(!deleteGenerated)}
|
onChange={() => setDeleteGenerated(!deleteGenerated)}
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ const ModalComponent: React.FC<IModal> = ({
|
|||||||
disabled={isRunning || disabled}
|
disabled={isRunning || disabled}
|
||||||
variant={accept?.variant ?? "primary"}
|
variant={accept?.variant ?? "primary"}
|
||||||
onClick={accept?.onClick}
|
onClick={accept?.onClick}
|
||||||
|
className="ml-2"
|
||||||
>
|
>
|
||||||
{isRunning ? (
|
{isRunning ? (
|
||||||
<Spinner animation="border" role="status" size="sm" />
|
<Spinner animation="border" role="status" size="sm" />
|
||||||
|
|||||||
@@ -222,7 +222,7 @@ export class ListFilterModel {
|
|||||||
break;
|
break;
|
||||||
case FilterMode.Galleries:
|
case FilterMode.Galleries:
|
||||||
this.sortBy = "path";
|
this.sortBy = "path";
|
||||||
this.sortByOptions = ["path"];
|
this.sortByOptions = ["path", "images_count"];
|
||||||
this.displayModeOptions = [DisplayMode.Grid, DisplayMode.List];
|
this.displayModeOptions = [DisplayMode.Grid, DisplayMode.List];
|
||||||
this.criterionOptions = [
|
this.criterionOptions = [
|
||||||
new NoneCriterionOption(),
|
new NoneCriterionOption(),
|
||||||
|
|||||||
Reference in New Issue
Block a user