mirror of
https://github.com/stashapp/stash.git
synced 2025-12-17 04:14:39 +03:00
Add options to delete file and generated files
This commit is contained in:
@@ -26,6 +26,6 @@ mutation SceneUpdate(
|
||||
}
|
||||
}
|
||||
|
||||
mutation SceneDestroy($id: ID!, $delete_file: Boolean) {
|
||||
sceneDestroy(input: {id: $id, delete_file: $delete_file})
|
||||
mutation SceneDestroy($id: ID!, $delete_file: Boolean, $delete_generated : Boolean) {
|
||||
sceneDestroy(input: {id: $id, delete_file: $delete_file, delete_generated: $delete_generated})
|
||||
}
|
||||
@@ -56,6 +56,7 @@ input SceneUpdateInput {
|
||||
input SceneDestroyInput {
|
||||
id: ID!
|
||||
delete_file: Boolean
|
||||
delete_generated: Boolean
|
||||
}
|
||||
|
||||
type FindScenesResultType {
|
||||
|
||||
@@ -4,12 +4,15 @@ import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/stashapp/stash/pkg/database"
|
||||
"github.com/stashapp/stash/pkg/logger"
|
||||
"github.com/stashapp/stash/pkg/manager"
|
||||
"github.com/stashapp/stash/pkg/models"
|
||||
"github.com/stashapp/stash/pkg/utils"
|
||||
)
|
||||
|
||||
func (r *mutationResolver) SceneUpdate(ctx context.Context, input models.SceneUpdateInput) (*models.Scene, error) {
|
||||
@@ -145,6 +148,12 @@ func (r *mutationResolver) SceneDestroy(ctx context.Context, input models.SceneD
|
||||
return false, err
|
||||
}
|
||||
|
||||
// if delete generated is true, then delete the generated files
|
||||
// for the scene
|
||||
if input.DeleteGenerated != nil && *input.DeleteGenerated {
|
||||
deleteGeneratedSceneFiles(scene)
|
||||
}
|
||||
|
||||
// if delete file is true, then delete the file as well
|
||||
// if it fails, just log a message
|
||||
if input.DeleteFile != nil && *input.DeleteFile {
|
||||
@@ -157,6 +166,81 @@ func (r *mutationResolver) SceneDestroy(ctx context.Context, input models.SceneD
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func deleteGeneratedSceneFiles(scene *models.Scene) {
|
||||
markersFolder := filepath.Join(manager.GetInstance().Paths.Generated.Markers, scene.Checksum)
|
||||
|
||||
exists, _ := utils.FileExists(markersFolder)
|
||||
if exists {
|
||||
err := os.RemoveAll(markersFolder)
|
||||
if err != nil {
|
||||
logger.Warnf("Could not delete file %s: %s", scene.Path, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
thumbPath := manager.GetInstance().Paths.Scene.GetThumbnailScreenshotPath(scene.Checksum)
|
||||
exists, _ = utils.FileExists(thumbPath)
|
||||
if exists {
|
||||
err := os.Remove(thumbPath)
|
||||
if err != nil {
|
||||
logger.Warnf("Could not delete file %s: %s", thumbPath, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
normalPath := manager.GetInstance().Paths.Scene.GetScreenshotPath(scene.Checksum)
|
||||
exists, _ = utils.FileExists(normalPath)
|
||||
if exists {
|
||||
err := os.Remove(normalPath)
|
||||
if err != nil {
|
||||
logger.Warnf("Could not delete file %s: %s", normalPath, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
streamPreviewPath := manager.GetInstance().Paths.Scene.GetStreamPreviewPath(scene.Checksum)
|
||||
exists, _ = utils.FileExists(streamPreviewPath)
|
||||
if exists {
|
||||
err := os.Remove(streamPreviewPath)
|
||||
if err != nil {
|
||||
logger.Warnf("Could not delete file %s: %s", streamPreviewPath, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
streamPreviewImagePath := manager.GetInstance().Paths.Scene.GetStreamPreviewImagePath(scene.Checksum)
|
||||
exists, _ = utils.FileExists(streamPreviewImagePath)
|
||||
if exists {
|
||||
err := os.Remove(streamPreviewImagePath)
|
||||
if err != nil {
|
||||
logger.Warnf("Could not delete file %s: %s", streamPreviewImagePath, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
transcodePath := manager.GetInstance().Paths.Scene.GetTranscodePath(scene.Checksum)
|
||||
exists, _ = utils.FileExists(transcodePath)
|
||||
if exists {
|
||||
err := os.Remove(transcodePath)
|
||||
if err != nil {
|
||||
logger.Warnf("Could not delete file %s: %s", transcodePath, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
spritePath := manager.GetInstance().Paths.Scene.GetSpriteImageFilePath(scene.Checksum)
|
||||
exists, _ = utils.FileExists(spritePath)
|
||||
if exists {
|
||||
err := os.Remove(spritePath)
|
||||
if err != nil {
|
||||
logger.Warnf("Could not delete file %s: %s", spritePath, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
vttPath := manager.GetInstance().Paths.Scene.GetSpriteVttFilePath(scene.Checksum)
|
||||
exists, _ = utils.FileExists(vttPath)
|
||||
if exists {
|
||||
err := os.Remove(vttPath)
|
||||
if err != nil {
|
||||
logger.Warnf("Could not delete file %s: %s", vttPath, err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (r *mutationResolver) SceneMarkerCreate(ctx context.Context, input models.SceneMarkerCreateInput) (*models.SceneMarker, error) {
|
||||
primaryTagID, _ := strconv.Atoi(input.PrimaryTagID)
|
||||
sceneID, _ := strconv.Atoi(input.SceneID)
|
||||
|
||||
@@ -2176,6 +2176,7 @@ input SceneUpdateInput {
|
||||
input SceneDestroyInput {
|
||||
id: ID!
|
||||
delete_file: Boolean
|
||||
delete_generated: Boolean
|
||||
}
|
||||
|
||||
type FindScenesResultType {
|
||||
@@ -8355,6 +8356,12 @@ func (ec *executionContext) unmarshalInputSceneDestroyInput(ctx context.Context,
|
||||
if err != nil {
|
||||
return it, err
|
||||
}
|
||||
case "delete_generated":
|
||||
var err error
|
||||
it.DeleteGenerated, err = ec.unmarshalOBoolean2ᚖbool(ctx, v)
|
||||
if err != nil {
|
||||
return it, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -137,8 +137,9 @@ type PerformerUpdateInput struct {
|
||||
}
|
||||
|
||||
type SceneDestroyInput struct {
|
||||
ID string `json:"id"`
|
||||
DeleteFile *bool `json:"delete_file"`
|
||||
ID string `json:"id"`
|
||||
DeleteFile *bool `json:"delete_file"`
|
||||
DeleteGenerated *bool `json:"delete_generated"`
|
||||
}
|
||||
|
||||
type SceneFileType struct {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import {
|
||||
Alert,
|
||||
Button,
|
||||
Classes,
|
||||
Checkbox,
|
||||
Dialog,
|
||||
FormGroup,
|
||||
HTMLSelect,
|
||||
InputGroup,
|
||||
@@ -37,6 +39,7 @@ export const SceneEditPanel: FunctionComponent<IProps> = (props: IProps) => {
|
||||
|
||||
const [isDeleteAlertOpen, setIsDeleteAlertOpen] = useState<boolean>(false);
|
||||
const [deleteFile, setDeleteFile] = useState<boolean>(false);
|
||||
const [deleteGenerated, setDeleteGenerated] = useState<boolean>(true);
|
||||
|
||||
// Network state
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
@@ -98,7 +101,8 @@ export const SceneEditPanel: FunctionComponent<IProps> = (props: IProps) => {
|
||||
function getSceneDeleteInput(): GQL.SceneDestroyInput {
|
||||
return {
|
||||
id: props.scene.id,
|
||||
delete_file: deleteFile
|
||||
delete_file: deleteFile,
|
||||
delete_generated: deleteGenerated
|
||||
};
|
||||
}
|
||||
|
||||
@@ -134,19 +138,31 @@ export const SceneEditPanel: FunctionComponent<IProps> = (props: IProps) => {
|
||||
|
||||
function renderDeleteAlert() {
|
||||
return (
|
||||
<Alert
|
||||
cancelButtonText="Cancel"
|
||||
confirmButtonText="Delete"
|
||||
<>
|
||||
<Dialog
|
||||
canOutsideClickClose={false}
|
||||
canEscapeKeyClose={false}
|
||||
icon="trash"
|
||||
intent="danger"
|
||||
isCloseButtonShown={false}
|
||||
isOpen={isDeleteAlertOpen}
|
||||
onCancel={() => setIsDeleteAlertOpen(false)}
|
||||
onConfirm={() => onDelete()}
|
||||
title="Delete Scene?"
|
||||
>
|
||||
<p>
|
||||
Are you sure you want to delete this scene? Unless the file is also deleted, this scene will be re-added when scan is performed.
|
||||
</p>
|
||||
</Alert>
|
||||
<div className={Classes.DIALOG_BODY}>
|
||||
<p>
|
||||
Are you sure you want to delete this scene? Unless the file is also deleted, this scene will be re-added when scan is performed.
|
||||
</p>
|
||||
<Checkbox checked={deleteFile} label="Delete file" onChange={() => setDeleteFile(!deleteFile)} />
|
||||
<Checkbox checked={deleteGenerated} label="Delete generated supporting files" onChange={() => setDeleteGenerated(!deleteGenerated)} />
|
||||
</div>
|
||||
|
||||
<div className={Classes.DIALOG_FOOTER}>
|
||||
<div className={Classes.DIALOG_FOOTER_ACTIONS}>
|
||||
<Button intent="danger" onClick={() => onDelete()}>Delete</Button>
|
||||
<Button onClick={() => setIsDeleteAlertOpen(false)}>Cancel</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// Generated in 2019-08-15T13:55:54+10:00
|
||||
// Generated in 2019-08-15T18:05:18+10:00
|
||||
export type Maybe<T> = T | undefined;
|
||||
|
||||
export interface SceneFilterType {
|
||||
@@ -92,6 +92,8 @@ export interface SceneDestroyInput {
|
||||
id: string;
|
||||
|
||||
delete_file?: Maybe<boolean>;
|
||||
|
||||
delete_generated?: Maybe<boolean>;
|
||||
}
|
||||
|
||||
export interface SceneMarkerCreateInput {
|
||||
@@ -399,6 +401,7 @@ export type SceneUpdateSceneUpdate = SceneDataFragment;
|
||||
export type SceneDestroyVariables = {
|
||||
id: string;
|
||||
delete_file?: Maybe<boolean>;
|
||||
delete_generated?: Maybe<boolean>;
|
||||
};
|
||||
|
||||
export type SceneDestroyMutation = {
|
||||
@@ -1792,8 +1795,18 @@ export function useSceneUpdate(
|
||||
>(SceneUpdateDocument, baseOptions);
|
||||
}
|
||||
export const SceneDestroyDocument = gql`
|
||||
mutation SceneDestroy($id: ID!, $delete_file: Boolean) {
|
||||
sceneDestroy(input: { id: $id, delete_file: $delete_file })
|
||||
mutation SceneDestroy(
|
||||
$id: ID!
|
||||
$delete_file: Boolean
|
||||
$delete_generated: Boolean
|
||||
) {
|
||||
sceneDestroy(
|
||||
input: {
|
||||
id: $id
|
||||
delete_file: $delete_file
|
||||
delete_generated: $delete_generated
|
||||
}
|
||||
)
|
||||
}
|
||||
`;
|
||||
export function useSceneDestroy(
|
||||
|
||||
Reference in New Issue
Block a user