Merge branch 'master' into delete_scene

This commit is contained in:
WithoutPants
2019-08-20 15:37:58 +10:00
committed by GitHub
21 changed files with 458 additions and 17 deletions

View File

@@ -175,3 +175,17 @@ func (r *mutationResolver) PerformerUpdate(ctx context.Context, input models.Per
return performer, nil
}
func (r *mutationResolver) PerformerDestroy(ctx context.Context, input models.PerformerDestroyInput) (bool, error) {
qb := models.NewPerformerQueryBuilder()
tx := database.DB.MustBeginTx(ctx, nil)
if err := qb.Destroy(input.ID, tx); err != nil {
_ = tx.Rollback()
return false, err
}
if err := tx.Commit(); err != nil {
return false, err
}
return true, nil
}

View File

@@ -3,11 +3,12 @@ package api
import (
"context"
"database/sql"
"strconv"
"time"
"github.com/stashapp/stash/pkg/database"
"github.com/stashapp/stash/pkg/models"
"github.com/stashapp/stash/pkg/utils"
"strconv"
"time"
)
func (r *mutationResolver) StudioCreate(ctx context.Context, input models.StudioCreateInput) (*models.Studio, error) {
@@ -85,3 +86,16 @@ func (r *mutationResolver) StudioUpdate(ctx context.Context, input models.Studio
return studio, nil
}
func (r *mutationResolver) StudioDestroy(ctx context.Context, input models.StudioDestroyInput) (bool, error) {
qb := models.NewStudioQueryBuilder()
tx := database.DB.MustBeginTx(ctx, nil)
if err := qb.Destroy(input.ID, tx); err != nil {
_ = tx.Rollback()
return false, err
}
if err := tx.Commit(); err != nil {
return false, err
}
return true, nil
}

View File

@@ -6,6 +6,7 @@ import (
"math"
"os"
"os/exec"
"path/filepath"
"strconv"
"strings"
"time"
@@ -28,6 +29,8 @@ type VideoFile struct {
VideoStream *FFProbeStream
Path string
Title string
Comment string
Container string
Duration float64
StartTime float64
@@ -82,6 +85,14 @@ func parse(filePath string, probeJSON *FFProbeJSON) (*VideoFile, error) {
//} // TODO nil_or_unsupported.(video_stream) && nil_or_unsupported.(audio_stream)
result.Path = filePath
result.Title = probeJSON.Format.Tags.Title
if result.Title == "" {
// default title to filename
result.Title = filepath.Base(result.Path)
}
result.Comment = probeJSON.Format.Tags.Comment
result.Bitrate, _ = strconv.ParseInt(probeJSON.Format.BitRate, 10, 64)
result.Container = probeJSON.Format.FormatName

View File

@@ -22,6 +22,8 @@ type FFProbeJSON struct {
Encoder string `json:"encoder"`
MajorBrand string `json:"major_brand"`
MinorVersion string `json:"minor_version"`
Title string `json:"title"`
Comment string `json:"comment"`
} `json:"tags"`
} `json:"format"`
Streams []FFProbeStream `json:"streams"`

View File

@@ -1,13 +1,14 @@
package manager
import (
"path/filepath"
"sync"
"github.com/bmatcuk/doublestar"
"github.com/stashapp/stash/pkg/logger"
"github.com/stashapp/stash/pkg/manager/config"
"github.com/stashapp/stash/pkg/models"
"github.com/stashapp/stash/pkg/utils"
"path/filepath"
"sync"
)
func (s *singleton) Scan() {
@@ -34,6 +35,8 @@ func (s *singleton) Scan() {
go task.Start(&wg)
wg.Wait()
}
logger.Info("Finished scan")
}()
}

View File

@@ -3,15 +3,16 @@ package manager
import (
"context"
"database/sql"
"path/filepath"
"strconv"
"sync"
"time"
"github.com/stashapp/stash/pkg/database"
"github.com/stashapp/stash/pkg/ffmpeg"
"github.com/stashapp/stash/pkg/logger"
"github.com/stashapp/stash/pkg/models"
"github.com/stashapp/stash/pkg/utils"
"path/filepath"
"strconv"
"sync"
"time"
)
type ScanTask struct {
@@ -46,9 +47,15 @@ func (t *ScanTask) scanGallery() {
tx := database.DB.MustBeginTx(ctx, nil)
gallery, _ = qb.FindByChecksum(checksum, tx)
if gallery != nil {
logger.Infof("%s already exists. Updating path...", t.FilePath)
gallery.Path = t.FilePath
_, err = qb.Update(*gallery, tx)
exists, _ := utils.FileExists(t.FilePath)
if exists {
logger.Infof("%s already exists. Duplicate of %s ", t.FilePath, gallery.Path)
} else {
logger.Infof("%s already exists. Updating path...", t.FilePath)
gallery.Path = t.FilePath
_, err = qb.Update(*gallery, tx)
}
} else {
logger.Infof("%s doesn't exist. Creating new item...", t.FilePath)
currentTime := time.Now()
@@ -95,15 +102,23 @@ func (t *ScanTask) scanScene() {
ctx := context.TODO()
tx := database.DB.MustBeginTx(ctx, nil)
if scene != nil {
logger.Infof("%s already exists. Updating path...", t.FilePath)
scene.Path = t.FilePath
_, err = qb.Update(*scene, tx)
exists, _ := utils.FileExists(t.FilePath)
if exists {
logger.Infof("%s already exists. Duplicate of %s ", t.FilePath, scene.Path)
} else {
logger.Infof("%s already exists. Updating path...", t.FilePath)
scene.Path = t.FilePath
_, err = qb.Update(*scene, tx)
}
} else {
logger.Infof("%s doesn't exist. Creating new item...", t.FilePath)
currentTime := time.Now()
newScene := models.Scene{
Checksum: checksum,
Path: t.FilePath,
Title: sql.NullString{String: videoFile.Title, Valid: true},
Details: sql.NullString{String: videoFile.Comment, Valid: true},
Date: models.SQLiteDate{String: videoFile.CreationTime.Format("2006-01-02")},
Duration: sql.NullFloat64{Float64: videoFile.Duration, Valid: true},
VideoCodec: sql.NullString{String: videoFile.VideoCodec, Valid: true},
AudioCodec: sql.NullString{String: videoFile.AudioCodec, Valid: true},

View File

@@ -108,6 +108,7 @@ type ComplexityRoot struct {
Mutation struct {
ConfigureGeneral func(childComplexity int, input ConfigGeneralInput) int
PerformerCreate func(childComplexity int, input PerformerCreateInput) int
PerformerDestroy func(childComplexity int, input PerformerDestroyInput) int
PerformerUpdate func(childComplexity int, input PerformerUpdateInput) int
SceneDestroy func(childComplexity int, input SceneDestroyInput) int
SceneMarkerCreate func(childComplexity int, input SceneMarkerCreateInput) int
@@ -115,6 +116,7 @@ type ComplexityRoot struct {
SceneMarkerUpdate func(childComplexity int, input SceneMarkerUpdateInput) int
SceneUpdate func(childComplexity int, input SceneUpdateInput) int
StudioCreate func(childComplexity int, input StudioCreateInput) int
StudioDestroy func(childComplexity int, input StudioDestroyInput) int
StudioUpdate func(childComplexity int, input StudioUpdateInput) int
TagCreate func(childComplexity int, input TagCreateInput) int
TagDestroy func(childComplexity int, input TagDestroyInput) int
@@ -290,8 +292,10 @@ type MutationResolver interface {
SceneMarkerDestroy(ctx context.Context, id string) (bool, error)
PerformerCreate(ctx context.Context, input PerformerCreateInput) (*Performer, error)
PerformerUpdate(ctx context.Context, input PerformerUpdateInput) (*Performer, error)
PerformerDestroy(ctx context.Context, input PerformerDestroyInput) (bool, error)
StudioCreate(ctx context.Context, input StudioCreateInput) (*Studio, error)
StudioUpdate(ctx context.Context, input StudioUpdateInput) (*Studio, error)
StudioDestroy(ctx context.Context, input StudioDestroyInput) (bool, error)
TagCreate(ctx context.Context, input TagCreateInput) (*Tag, error)
TagUpdate(ctx context.Context, input TagUpdateInput) (*Tag, error)
TagDestroy(ctx context.Context, input TagDestroyInput) (bool, error)
@@ -600,6 +604,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.Mutation.PerformerCreate(childComplexity, args["input"].(PerformerCreateInput)), true
case "Mutation.performerDestroy":
if e.complexity.Mutation.PerformerDestroy == nil {
break
}
args, err := ec.field_Mutation_performerDestroy_args(context.TODO(), rawArgs)
if err != nil {
return 0, false
}
return e.complexity.Mutation.PerformerDestroy(childComplexity, args["input"].(PerformerDestroyInput)), true
case "Mutation.performerUpdate":
if e.complexity.Mutation.PerformerUpdate == nil {
break
@@ -684,6 +700,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.Mutation.StudioCreate(childComplexity, args["input"].(StudioCreateInput)), true
case "Mutation.studioDestroy":
if e.complexity.Mutation.StudioDestroy == nil {
break
}
args, err := ec.field_Mutation_studioDestroy_args(context.TODO(), rawArgs)
if err != nil {
return 0, false
}
return e.complexity.Mutation.StudioDestroy(childComplexity, args["input"].(StudioDestroyInput)), true
case "Mutation.studioUpdate":
if e.complexity.Mutation.StudioUpdate == nil {
break
@@ -1855,9 +1883,11 @@ type Mutation {
performerCreate(input: PerformerCreateInput!): Performer
performerUpdate(input: PerformerUpdateInput!): Performer
performerDestroy(input: PerformerDestroyInput!): Boolean!
studioCreate(input: StudioCreateInput!): Studio
studioUpdate(input: StudioUpdateInput!): Studio
studioDestroy(input: StudioDestroyInput!): Boolean!
tagCreate(input: TagCreateInput!): Tag
tagUpdate(input: TagUpdateInput!): Tag
@@ -2069,6 +2099,10 @@ input PerformerUpdateInput {
image: String
}
input PerformerDestroyInput {
id: ID!
}
type FindPerformersResultType {
count: Int!
performers: [Performer!]!
@@ -2233,6 +2267,10 @@ input StudioUpdateInput {
image: String
}
input StudioDestroyInput {
id: ID!
}
type FindStudiosResultType {
count: Int!
studios: [Studio!]!
@@ -2291,6 +2329,20 @@ func (ec *executionContext) field_Mutation_performerCreate_args(ctx context.Cont
return args, nil
}
func (ec *executionContext) field_Mutation_performerDestroy_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
var err error
args := map[string]interface{}{}
var arg0 PerformerDestroyInput
if tmp, ok := rawArgs["input"]; ok {
arg0, err = ec.unmarshalNPerformerDestroyInput2githubᚗcomᚋstashappᚋstashᚋpkgᚋmodelsᚐPerformerDestroyInput(ctx, tmp)
if err != nil {
return nil, err
}
}
args["input"] = arg0
return args, nil
}
func (ec *executionContext) field_Mutation_performerUpdate_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
var err error
args := map[string]interface{}{}
@@ -2389,6 +2441,20 @@ func (ec *executionContext) field_Mutation_studioCreate_args(ctx context.Context
return args, nil
}
func (ec *executionContext) field_Mutation_studioDestroy_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
var err error
args := map[string]interface{}{}
var arg0 StudioDestroyInput
if tmp, ok := rawArgs["input"]; ok {
arg0, err = ec.unmarshalNStudioDestroyInput2githubᚗcomᚋstashappᚋstashᚋpkgᚋmodelsᚐStudioDestroyInput(ctx, tmp)
if err != nil {
return nil, err
}
}
args["input"] = arg0
return args, nil
}
func (ec *executionContext) field_Mutation_studioUpdate_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
var err error
args := map[string]interface{}{}
@@ -3694,6 +3760,40 @@ func (ec *executionContext) _Mutation_performerUpdate(ctx context.Context, field
return ec.marshalOPerformer2ᚖgithubᚗcomᚋstashappᚋstashᚋpkgᚋmodelsᚐPerformer(ctx, field.Selections, res)
}
func (ec *executionContext) _Mutation_performerDestroy(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_performerDestroy_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().PerformerDestroy(rctx, args["input"].(PerformerDestroyInput))
})
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_studioCreate(ctx context.Context, field graphql.CollectedField) graphql.Marshaler {
ctx = ec.Tracer.StartFieldExecution(ctx, field)
defer func() { ec.Tracer.EndFieldExecution(ctx) }()
@@ -3756,6 +3856,40 @@ func (ec *executionContext) _Mutation_studioUpdate(ctx context.Context, field gr
return ec.marshalOStudio2ᚖgithubᚗcomᚋstashappᚋstashᚋpkgᚋmodelsᚐStudio(ctx, field.Selections, res)
}
func (ec *executionContext) _Mutation_studioDestroy(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_studioDestroy_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().StudioDestroy(rctx, args["input"].(StudioDestroyInput))
})
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_tagCreate(ctx context.Context, field graphql.CollectedField) graphql.Marshaler {
ctx = ec.Tracer.StartFieldExecution(ctx, field)
defer func() { ec.Tracer.EndFieldExecution(ctx) }()
@@ -8200,6 +8334,24 @@ func (ec *executionContext) unmarshalInputPerformerCreateInput(ctx context.Conte
return it, nil
}
func (ec *executionContext) unmarshalInputPerformerDestroyInput(ctx context.Context, v interface{}) (PerformerDestroyInput, error) {
var it PerformerDestroyInput
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
}
}
}
return it, nil
}
func (ec *executionContext) unmarshalInputPerformerFilterType(ctx context.Context, v interface{}) (PerformerFilterType, error) {
var it PerformerFilterType
var asMap = v.(map[string]interface{})
@@ -8656,6 +8808,24 @@ func (ec *executionContext) unmarshalInputStudioCreateInput(ctx context.Context,
return it, nil
}
func (ec *executionContext) unmarshalInputStudioDestroyInput(ctx context.Context, v interface{}) (StudioDestroyInput, error) {
var it StudioDestroyInput
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
}
}
}
return it, nil
}
func (ec *executionContext) unmarshalInputStudioUpdateInput(ctx context.Context, v interface{}) (StudioUpdateInput, error) {
var it StudioUpdateInput
var asMap = v.(map[string]interface{})
@@ -9149,10 +9319,20 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet)
out.Values[i] = ec._Mutation_performerCreate(ctx, field)
case "performerUpdate":
out.Values[i] = ec._Mutation_performerUpdate(ctx, field)
case "performerDestroy":
out.Values[i] = ec._Mutation_performerDestroy(ctx, field)
if out.Values[i] == graphql.Null {
invalids++
}
case "studioCreate":
out.Values[i] = ec._Mutation_studioCreate(ctx, field)
case "studioUpdate":
out.Values[i] = ec._Mutation_studioUpdate(ctx, field)
case "studioDestroy":
out.Values[i] = ec._Mutation_studioDestroy(ctx, field)
if out.Values[i] == graphql.Null {
invalids++
}
case "tagCreate":
out.Values[i] = ec._Mutation_tagCreate(ctx, field)
case "tagUpdate":
@@ -11114,6 +11294,10 @@ func (ec *executionContext) unmarshalNPerformerCreateInput2githubᚗcomᚋstasha
return ec.unmarshalInputPerformerCreateInput(ctx, v)
}
func (ec *executionContext) unmarshalNPerformerDestroyInput2githubᚗcomᚋstashappᚋstashᚋpkgᚋmodelsᚐPerformerDestroyInput(ctx context.Context, v interface{}) (PerformerDestroyInput, error) {
return ec.unmarshalInputPerformerDestroyInput(ctx, v)
}
func (ec *executionContext) unmarshalNPerformerUpdateInput2githubᚗcomᚋstashappᚋstashᚋpkgᚋmodelsᚐPerformerUpdateInput(ctx context.Context, v interface{}) (PerformerUpdateInput, error) {
return ec.unmarshalInputPerformerUpdateInput(ctx, v)
}
@@ -11427,6 +11611,10 @@ func (ec *executionContext) unmarshalNStudioCreateInput2githubᚗcomᚋstashapp
return ec.unmarshalInputStudioCreateInput(ctx, v)
}
func (ec *executionContext) unmarshalNStudioDestroyInput2githubᚗcomᚋstashappᚋstashᚋpkgᚋmodelsᚐStudioDestroyInput(ctx context.Context, v interface{}) (StudioDestroyInput, error) {
return ec.unmarshalInputStudioDestroyInput(ctx, v)
}
func (ec *executionContext) unmarshalNStudioUpdateInput2githubᚗcomᚋstashappᚋstashᚋpkgᚋmodelsᚐStudioUpdateInput(ctx context.Context, v interface{}) (StudioUpdateInput, error) {
return ec.unmarshalInputStudioUpdateInput(ctx, v)
}

View File

@@ -109,6 +109,10 @@ type PerformerCreateInput struct {
Image string `json:"image"`
}
type PerformerDestroyInput struct {
ID string `json:"id"`
}
type PerformerFilterType struct {
// Filter by favorite
FilterFavorites *bool `json:"filter_favorites"`
@@ -260,6 +264,10 @@ type StudioCreateInput struct {
Image string `json:"image"`
}
type StudioDestroyInput struct {
ID string `json:"id"`
}
type StudioUpdateInput struct {
ID string `json:"id"`
Name *string `json:"name"`

View File

@@ -2,6 +2,7 @@ package models
import (
"database/sql"
"github.com/jmoiron/sqlx"
"github.com/stashapp/stash/pkg/database"
)
@@ -54,6 +55,15 @@ func (qb *PerformerQueryBuilder) Update(updatedPerformer Performer, tx *sqlx.Tx)
return &updatedPerformer, nil
}
func (qb *PerformerQueryBuilder) Destroy(id string, tx *sqlx.Tx) error {
_, err := tx.Exec("DELETE FROM performers_scenes WHERE performer_id = ?", id)
if err != nil {
return err
}
return executeDeleteQuery("performers", id, tx)
}
func (qb *PerformerQueryBuilder) Find(id int) (*Performer, error) {
query := "SELECT * FROM performers WHERE id = ? LIMIT 1"
args := []interface{}{id}

View File

@@ -2,6 +2,7 @@ package models
import (
"database/sql"
"github.com/jmoiron/sqlx"
"github.com/stashapp/stash/pkg/database"
)
@@ -50,6 +51,22 @@ func (qb *StudioQueryBuilder) Update(updatedStudio Studio, tx *sqlx.Tx) (*Studio
return &updatedStudio, nil
}
func (qb *StudioQueryBuilder) Destroy(id string, tx *sqlx.Tx) error {
// remove studio from scenes
_, err := tx.Exec("UPDATE scenes SET studio_id = null WHERE studio_id = ?", id)
if err != nil {
return err
}
// remove studio from scraped items
_, err = tx.Exec("UPDATE scraped_items SET studio_id = null WHERE studio_id = ?", id)
if err != nil {
return err
}
return executeDeleteQuery("studios", id, tx)
}
func (qb *StudioQueryBuilder) Find(id int, tx *sqlx.Tx) (*Studio, error) {
query := "SELECT * FROM studios WHERE id = ? LIMIT 1"
args := []interface{}{id}
@@ -86,7 +103,7 @@ func (qb *StudioQueryBuilder) Query(findFilter *FindFilterType) ([]*Studio, int)
var args []interface{}
body := selectDistinctIDs("studios")
body += `
join scenes on studios.id = scenes.studio_id
left join scenes on studios.id = scenes.studio_id
`
if q := findFilter.Q; q != nil && *q != "" {