Add delete scene button

This commit is contained in:
WithoutPants
2019-08-15 17:32:57 +10:00
parent 39bdede110
commit cfe2636837
12 changed files with 317 additions and 6 deletions

View File

@@ -3,10 +3,13 @@ package api
import (
"context"
"database/sql"
"github.com/stashapp/stash/pkg/database"
"github.com/stashapp/stash/pkg/models"
"os"
"strconv"
"time"
"github.com/stashapp/stash/pkg/database"
"github.com/stashapp/stash/pkg/logger"
"github.com/stashapp/stash/pkg/models"
)
func (r *mutationResolver) SceneUpdate(ctx context.Context, input models.SceneUpdateInput) (*models.Scene, error) {
@@ -101,6 +104,59 @@ func (r *mutationResolver) SceneUpdate(ctx context.Context, input models.SceneUp
return scene, nil
}
func (r *mutationResolver) SceneDestroy(ctx context.Context, input models.SceneDestroyInput) (bool, error) {
qb := models.NewSceneQueryBuilder()
jqb := models.NewJoinsQueryBuilder()
tx := database.DB.MustBeginTx(ctx, nil)
sceneID, _ := strconv.Atoi(input.ID)
scene, err := qb.Find(sceneID)
if err != nil {
_ = tx.Rollback()
return false, err
}
if err := jqb.DestroyScenesTags(sceneID, tx); err != nil {
_ = tx.Rollback()
return false, err
}
if err := jqb.DestroyPerformersScenes(sceneID, tx); err != nil {
_ = tx.Rollback()
return false, err
}
if err := jqb.DestroyScenesMarkers(sceneID, tx); err != nil {
_ = tx.Rollback()
return false, err
}
if err := jqb.DestroyScenesGalleries(sceneID, tx); err != nil {
_ = tx.Rollback()
return false, err
}
if err := qb.Destroy(input.ID, tx); err != nil {
_ = tx.Rollback()
return false, err
}
if err := tx.Commit(); err != nil {
return false, err
}
// if delete file is true, then delete the file as well
// if it fails, just log a message
if input.DeleteFile != nil && *input.DeleteFile {
err = os.Remove(scene.Path)
if err != nil {
logger.Warnf("Could not delete file %s: %s", scene.Path, err.Error())
}
}
return true, nil
}
func (r *mutationResolver) SceneMarkerCreate(ctx context.Context, input models.SceneMarkerCreateInput) (*models.SceneMarker, error) {
primaryTagID, _ := strconv.Atoi(input.PrimaryTagID)
sceneID, _ := strconv.Atoi(input.SceneID)

View File

@@ -109,6 +109,7 @@ type ComplexityRoot struct {
ConfigureGeneral func(childComplexity int, input ConfigGeneralInput) int
PerformerCreate func(childComplexity int, input PerformerCreateInput) int
PerformerUpdate func(childComplexity int, input PerformerUpdateInput) int
SceneDestroy func(childComplexity int, input SceneDestroyInput) int
SceneMarkerCreate func(childComplexity int, input SceneMarkerCreateInput) int
SceneMarkerDestroy func(childComplexity int, id string) int
SceneMarkerUpdate func(childComplexity int, input SceneMarkerUpdateInput) int
@@ -283,6 +284,7 @@ type GalleryResolver interface {
}
type MutationResolver interface {
SceneUpdate(ctx context.Context, input SceneUpdateInput) (*Scene, error)
SceneDestroy(ctx context.Context, input SceneDestroyInput) (bool, error)
SceneMarkerCreate(ctx context.Context, input SceneMarkerCreateInput) (*SceneMarker, error)
SceneMarkerUpdate(ctx context.Context, input SceneMarkerUpdateInput) (*SceneMarker, error)
SceneMarkerDestroy(ctx context.Context, id string) (bool, error)
@@ -610,6 +612,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.Mutation.PerformerUpdate(childComplexity, args["input"].(PerformerUpdateInput)), true
case "Mutation.sceneDestroy":
if e.complexity.Mutation.SceneDestroy == nil {
break
}
args, err := ec.field_Mutation_sceneDestroy_args(context.TODO(), rawArgs)
if err != nil {
return 0, false
}
return e.complexity.Mutation.SceneDestroy(childComplexity, args["input"].(SceneDestroyInput)), true
case "Mutation.sceneMarkerCreate":
if e.complexity.Mutation.SceneMarkerCreate == nil {
break
@@ -1833,6 +1847,7 @@ type Query {
type Mutation {
sceneUpdate(input: SceneUpdateInput!): Scene
sceneDestroy(input: SceneDestroyInput!): Boolean!
sceneMarkerCreate(input: SceneMarkerCreateInput!): SceneMarker
sceneMarkerUpdate(input: SceneMarkerUpdateInput!): SceneMarker
@@ -2158,6 +2173,11 @@ input SceneUpdateInput {
tag_ids: [ID!]
}
input SceneDestroyInput {
id: ID!
delete_file: Boolean
}
type FindScenesResultType {
count: Int!
scenes: [Scene!]!
@@ -2284,6 +2304,20 @@ func (ec *executionContext) field_Mutation_performerUpdate_args(ctx context.Cont
return args, nil
}
func (ec *executionContext) field_Mutation_sceneDestroy_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
var err error
args := map[string]interface{}{}
var arg0 SceneDestroyInput
if tmp, ok := rawArgs["input"]; ok {
arg0, err = ec.unmarshalNSceneDestroyInput2githubᚗcomᚋstashappᚋstashᚋpkgᚋmodelsᚐSceneDestroyInput(ctx, tmp)
if err != nil {
return nil, err
}
}
args["input"] = arg0
return args, nil
}
func (ec *executionContext) field_Mutation_sceneMarkerCreate_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
var err error
args := map[string]interface{}{}
@@ -3467,6 +3501,40 @@ func (ec *executionContext) _Mutation_sceneUpdate(ctx context.Context, field gra
return ec.marshalOScene2ᚖgithubᚗcomᚋstashappᚋstashᚋpkgᚋmodelsᚐScene(ctx, field.Selections, res)
}
func (ec *executionContext) _Mutation_sceneDestroy(ctx context.Context, field graphql.CollectedField) graphql.Marshaler {
ctx = ec.Tracer.StartFieldExecution(ctx, field)
defer func() { ec.Tracer.EndFieldExecution(ctx) }()
rctx := &graphql.ResolverContext{
Object: "Mutation",
Field: field,
Args: nil,
IsMethod: true,
}
ctx = graphql.WithResolverContext(ctx, rctx)
rawArgs := field.ArgumentMap(ec.Variables)
args, err := ec.field_Mutation_sceneDestroy_args(ctx, rawArgs)
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
rctx.Args = args
ctx = ec.Tracer.StartFieldResolverExecution(ctx, rctx)
resTmp := ec.FieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Mutation().SceneDestroy(rctx, args["input"].(SceneDestroyInput))
})
if resTmp == nil {
if !ec.HasError(rctx) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(bool)
rctx.Result = res
ctx = ec.Tracer.StartFieldChildExecution(ctx)
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}
func (ec *executionContext) _Mutation_sceneMarkerCreate(ctx context.Context, field graphql.CollectedField) graphql.Marshaler {
ctx = ec.Tracer.StartFieldExecution(ctx, field)
defer func() { ec.Tracer.EndFieldExecution(ctx) }()
@@ -8269,6 +8337,30 @@ func (ec *executionContext) unmarshalInputPerformerUpdateInput(ctx context.Conte
return it, nil
}
func (ec *executionContext) unmarshalInputSceneDestroyInput(ctx context.Context, v interface{}) (SceneDestroyInput, error) {
var it SceneDestroyInput
var asMap = v.(map[string]interface{})
for k, v := range asMap {
switch k {
case "id":
var err error
it.ID, err = ec.unmarshalNID2string(ctx, v)
if err != nil {
return it, err
}
case "delete_file":
var err error
it.DeleteFile, err = ec.unmarshalOBoolean2ᚖbool(ctx, v)
if err != nil {
return it, err
}
}
}
return it, nil
}
func (ec *executionContext) unmarshalInputSceneFilterType(ctx context.Context, v interface{}) (SceneFilterType, error) {
var it SceneFilterType
var asMap = v.(map[string]interface{})
@@ -9032,6 +9124,11 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet)
out.Values[i] = graphql.MarshalString("Mutation")
case "sceneUpdate":
out.Values[i] = ec._Mutation_sceneUpdate(ctx, field)
case "sceneDestroy":
out.Values[i] = ec._Mutation_sceneDestroy(ctx, field)
if out.Values[i] == graphql.Null {
invalids++
}
case "sceneMarkerCreate":
out.Values[i] = ec._Mutation_sceneMarkerCreate(ctx, field)
case "sceneMarkerUpdate":
@@ -11065,6 +11162,10 @@ func (ec *executionContext) marshalNScene2ᚖgithubᚗcomᚋstashappᚋstashᚋp
return ec._Scene(ctx, sel, v)
}
func (ec *executionContext) unmarshalNSceneDestroyInput2githubᚗcomᚋstashappᚋstashᚋpkgᚋmodelsᚐSceneDestroyInput(ctx context.Context, v interface{}) (SceneDestroyInput, error) {
return ec.unmarshalInputSceneDestroyInput(ctx, v)
}
func (ec *executionContext) marshalNSceneFileType2githubᚗcomᚋstashappᚋstashᚋpkgᚋmodelsᚐSceneFileType(ctx context.Context, sel ast.SelectionSet, v SceneFileType) graphql.Marshaler {
return ec._SceneFileType(ctx, sel, &v)
}

View File

@@ -136,6 +136,11 @@ type PerformerUpdateInput struct {
Image *string `json:"image"`
}
type SceneDestroyInput struct {
ID string `json:"id"`
DeleteFile *bool `json:"delete_file"`
}
type SceneFileType struct {
Size *string `json:"size"`
Duration *float64 `json:"duration"`

View File

@@ -33,6 +33,14 @@ func (qb *JoinsQueryBuilder) UpdatePerformersScenes(sceneID int, updatedJoins []
return qb.CreatePerformersScenes(updatedJoins, tx)
}
func (qb *JoinsQueryBuilder) DestroyPerformersScenes(sceneID int, tx *sqlx.Tx) error {
ensureTx(tx)
// Delete the existing joins
_, err := tx.Exec("DELETE FROM performers_scenes WHERE scene_id = ?", sceneID)
return err
}
func (qb *JoinsQueryBuilder) CreateScenesTags(newJoins []ScenesTags, tx *sqlx.Tx) error {
ensureTx(tx)
for _, join := range newJoins {
@@ -58,6 +66,15 @@ func (qb *JoinsQueryBuilder) UpdateScenesTags(sceneID int, updatedJoins []Scenes
return qb.CreateScenesTags(updatedJoins, tx)
}
func (qb *JoinsQueryBuilder) DestroyScenesTags(sceneID int, tx *sqlx.Tx) error {
ensureTx(tx)
// Delete the existing joins
_, err := tx.Exec("DELETE FROM scenes_tags WHERE scene_id = ?", sceneID)
return err
}
func (qb *JoinsQueryBuilder) CreateSceneMarkersTags(newJoins []SceneMarkersTags, tx *sqlx.Tx) error {
ensureTx(tx)
for _, join := range newJoins {
@@ -82,3 +99,32 @@ func (qb *JoinsQueryBuilder) UpdateSceneMarkersTags(sceneMarkerID int, updatedJo
}
return qb.CreateSceneMarkersTags(updatedJoins, tx)
}
func (qb *JoinsQueryBuilder) DestroySceneMarkersTags(sceneMarkerID int, updatedJoins []SceneMarkersTags, tx *sqlx.Tx) error {
ensureTx(tx)
// Delete the existing joins
_, err := tx.Exec("DELETE FROM scene_markers_tags WHERE scene_marker_id = ?", sceneMarkerID)
return err
}
func (qb *JoinsQueryBuilder) DestroyScenesGalleries(sceneID int, tx *sqlx.Tx) error {
ensureTx(tx)
// Unset the existing scene id from galleries
_, err := tx.Exec("UPDATE galleries SET scene_id = null WHERE scene_id = ?", sceneID)
return err
}
func (qb *JoinsQueryBuilder) DestroyScenesMarkers(sceneID int, tx *sqlx.Tx) error {
ensureTx(tx)
// Delete the scene marker tags
_, err := tx.Exec("DELETE t FROM scene_markers_tags t join scene_markers m on t.scene_marker_id = m.id WHERE m.scene_id = ?", sceneID)
// Delete the existing joins
_, err = tx.Exec("DELETE FROM scene_markers WHERE scene_id = ?", sceneID)
return err
}

View File

@@ -2,10 +2,11 @@ package models
import (
"database/sql"
"github.com/jmoiron/sqlx"
"github.com/stashapp/stash/pkg/database"
"strconv"
"strings"
"github.com/jmoiron/sqlx"
"github.com/stashapp/stash/pkg/database"
)
const scenesForPerformerQuery = `
@@ -76,6 +77,9 @@ func (qb *SceneQueryBuilder) Update(updatedScene Scene, tx *sqlx.Tx) (*Scene, er
return &updatedScene, nil
}
func (qb *SceneQueryBuilder) Destroy(id string, tx *sqlx.Tx) error {
return executeDeleteQuery("scenes", id, tx)
}
func (qb *SceneQueryBuilder) Find(id int) (*Scene, error) {
query := "SELECT * FROM scenes WHERE id = ? LIMIT 1"
args := []interface{}{id}