mirror of
https://github.com/stashapp/stash.git
synced 2025-12-17 12:24:38 +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) {
|
mutation SceneDestroy($id: ID!, $delete_file: Boolean, $delete_generated : Boolean) {
|
||||||
sceneDestroy(input: {id: $id, delete_file: $delete_file})
|
sceneDestroy(input: {id: $id, delete_file: $delete_file, delete_generated: $delete_generated})
|
||||||
}
|
}
|
||||||
@@ -56,6 +56,7 @@ input SceneUpdateInput {
|
|||||||
input SceneDestroyInput {
|
input SceneDestroyInput {
|
||||||
id: ID!
|
id: ID!
|
||||||
delete_file: Boolean
|
delete_file: Boolean
|
||||||
|
delete_generated: Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
type FindScenesResultType {
|
type FindScenesResultType {
|
||||||
|
|||||||
@@ -4,12 +4,15 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/stashapp/stash/pkg/database"
|
"github.com/stashapp/stash/pkg/database"
|
||||||
"github.com/stashapp/stash/pkg/logger"
|
"github.com/stashapp/stash/pkg/logger"
|
||||||
|
"github.com/stashapp/stash/pkg/manager"
|
||||||
"github.com/stashapp/stash/pkg/models"
|
"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) {
|
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
|
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 delete file is true, then delete the file as well
|
||||||
// if it fails, just log a message
|
// if it fails, just log a message
|
||||||
if input.DeleteFile != nil && *input.DeleteFile {
|
if input.DeleteFile != nil && *input.DeleteFile {
|
||||||
@@ -157,6 +166,81 @@ func (r *mutationResolver) SceneDestroy(ctx context.Context, input models.SceneD
|
|||||||
return true, nil
|
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) {
|
func (r *mutationResolver) SceneMarkerCreate(ctx context.Context, input models.SceneMarkerCreateInput) (*models.SceneMarker, error) {
|
||||||
primaryTagID, _ := strconv.Atoi(input.PrimaryTagID)
|
primaryTagID, _ := strconv.Atoi(input.PrimaryTagID)
|
||||||
sceneID, _ := strconv.Atoi(input.SceneID)
|
sceneID, _ := strconv.Atoi(input.SceneID)
|
||||||
|
|||||||
@@ -2176,6 +2176,7 @@ input SceneUpdateInput {
|
|||||||
input SceneDestroyInput {
|
input SceneDestroyInput {
|
||||||
id: ID!
|
id: ID!
|
||||||
delete_file: Boolean
|
delete_file: Boolean
|
||||||
|
delete_generated: Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
type FindScenesResultType {
|
type FindScenesResultType {
|
||||||
@@ -8355,6 +8356,12 @@ func (ec *executionContext) unmarshalInputSceneDestroyInput(ctx context.Context,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return it, err
|
return it, err
|
||||||
}
|
}
|
||||||
|
case "delete_generated":
|
||||||
|
var err error
|
||||||
|
it.DeleteGenerated, err = ec.unmarshalOBoolean2ᚖbool(ctx, v)
|
||||||
|
if err != nil {
|
||||||
|
return it, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -139,6 +139,7 @@ type PerformerUpdateInput struct {
|
|||||||
type SceneDestroyInput struct {
|
type SceneDestroyInput struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
DeleteFile *bool `json:"delete_file"`
|
DeleteFile *bool `json:"delete_file"`
|
||||||
|
DeleteGenerated *bool `json:"delete_generated"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type SceneFileType struct {
|
type SceneFileType struct {
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import {
|
import {
|
||||||
Alert,
|
|
||||||
Button,
|
Button,
|
||||||
|
Classes,
|
||||||
|
Checkbox,
|
||||||
|
Dialog,
|
||||||
FormGroup,
|
FormGroup,
|
||||||
HTMLSelect,
|
HTMLSelect,
|
||||||
InputGroup,
|
InputGroup,
|
||||||
@@ -37,6 +39,7 @@ export const SceneEditPanel: FunctionComponent<IProps> = (props: IProps) => {
|
|||||||
|
|
||||||
const [isDeleteAlertOpen, setIsDeleteAlertOpen] = useState<boolean>(false);
|
const [isDeleteAlertOpen, setIsDeleteAlertOpen] = useState<boolean>(false);
|
||||||
const [deleteFile, setDeleteFile] = useState<boolean>(false);
|
const [deleteFile, setDeleteFile] = useState<boolean>(false);
|
||||||
|
const [deleteGenerated, setDeleteGenerated] = useState<boolean>(true);
|
||||||
|
|
||||||
// Network state
|
// Network state
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
@@ -98,7 +101,8 @@ export const SceneEditPanel: FunctionComponent<IProps> = (props: IProps) => {
|
|||||||
function getSceneDeleteInput(): GQL.SceneDestroyInput {
|
function getSceneDeleteInput(): GQL.SceneDestroyInput {
|
||||||
return {
|
return {
|
||||||
id: props.scene.id,
|
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() {
|
function renderDeleteAlert() {
|
||||||
return (
|
return (
|
||||||
<Alert
|
<>
|
||||||
cancelButtonText="Cancel"
|
<Dialog
|
||||||
confirmButtonText="Delete"
|
canOutsideClickClose={false}
|
||||||
|
canEscapeKeyClose={false}
|
||||||
icon="trash"
|
icon="trash"
|
||||||
intent="danger"
|
isCloseButtonShown={false}
|
||||||
isOpen={isDeleteAlertOpen}
|
isOpen={isDeleteAlertOpen}
|
||||||
onCancel={() => setIsDeleteAlertOpen(false)}
|
title="Delete Scene?"
|
||||||
onConfirm={() => onDelete()}
|
|
||||||
>
|
>
|
||||||
|
<div className={Classes.DIALOG_BODY}>
|
||||||
<p>
|
<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.
|
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>
|
</p>
|
||||||
</Alert>
|
<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 */
|
/* tslint:disable */
|
||||||
/* eslint-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 type Maybe<T> = T | undefined;
|
||||||
|
|
||||||
export interface SceneFilterType {
|
export interface SceneFilterType {
|
||||||
@@ -92,6 +92,8 @@ export interface SceneDestroyInput {
|
|||||||
id: string;
|
id: string;
|
||||||
|
|
||||||
delete_file?: Maybe<boolean>;
|
delete_file?: Maybe<boolean>;
|
||||||
|
|
||||||
|
delete_generated?: Maybe<boolean>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SceneMarkerCreateInput {
|
export interface SceneMarkerCreateInput {
|
||||||
@@ -399,6 +401,7 @@ export type SceneUpdateSceneUpdate = SceneDataFragment;
|
|||||||
export type SceneDestroyVariables = {
|
export type SceneDestroyVariables = {
|
||||||
id: string;
|
id: string;
|
||||||
delete_file?: Maybe<boolean>;
|
delete_file?: Maybe<boolean>;
|
||||||
|
delete_generated?: Maybe<boolean>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type SceneDestroyMutation = {
|
export type SceneDestroyMutation = {
|
||||||
@@ -1792,8 +1795,18 @@ export function useSceneUpdate(
|
|||||||
>(SceneUpdateDocument, baseOptions);
|
>(SceneUpdateDocument, baseOptions);
|
||||||
}
|
}
|
||||||
export const SceneDestroyDocument = gql`
|
export const SceneDestroyDocument = gql`
|
||||||
mutation SceneDestroy($id: ID!, $delete_file: Boolean) {
|
mutation SceneDestroy(
|
||||||
sceneDestroy(input: { id: $id, delete_file: $delete_file })
|
$id: ID!
|
||||||
|
$delete_file: Boolean
|
||||||
|
$delete_generated: Boolean
|
||||||
|
) {
|
||||||
|
sceneDestroy(
|
||||||
|
input: {
|
||||||
|
id: $id
|
||||||
|
delete_file: $delete_file
|
||||||
|
delete_generated: $delete_generated
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
export function useSceneDestroy(
|
export function useSceneDestroy(
|
||||||
|
|||||||
Reference in New Issue
Block a user