mirror of
https://github.com/stashapp/stash.git
synced 2025-12-17 12:24:38 +03:00
Generate cover image (#376)
* Make mutating metadata ops mutation * Implement scene generate screenshot * Remove fetch policy on metadata mutations * Port UI changes to v2.5 * Set generated image in database
This commit is contained in:
27
graphql/documents/mutations/metadata.graphql
Normal file
27
graphql/documents/mutations/metadata.graphql
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
mutation MetadataImport {
|
||||||
|
metadataImport
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation MetadataExport {
|
||||||
|
metadataExport
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation MetadataScan($input: ScanMetadataInput!) {
|
||||||
|
metadataScan(input: $input)
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation MetadataGenerate($input: GenerateMetadataInput!) {
|
||||||
|
metadataGenerate(input: $input)
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation MetadataAutoTag($input: AutoTagMetadataInput!) {
|
||||||
|
metadataAutoTag(input: $input)
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation MetadataClean {
|
||||||
|
metadataClean
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation StopJob {
|
||||||
|
stopJob
|
||||||
|
}
|
||||||
@@ -78,4 +78,8 @@ mutation SceneResetO($id: ID!) {
|
|||||||
|
|
||||||
mutation SceneDestroy($id: ID!, $delete_file: Boolean, $delete_generated : Boolean) {
|
mutation SceneDestroy($id: ID!, $delete_file: Boolean, $delete_generated : Boolean) {
|
||||||
sceneDestroy(input: {id: $id, delete_file: $delete_file, delete_generated: $delete_generated})
|
sceneDestroy(input: {id: $id, delete_file: $delete_file, delete_generated: $delete_generated})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mutation SceneGenerateScreenshot($id: ID!, $at: Float) {
|
||||||
|
sceneGenerateScreenshot(id: $id, at: $at)
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,27 +1,3 @@
|
|||||||
query MetadataImport {
|
|
||||||
metadataImport
|
|
||||||
}
|
|
||||||
|
|
||||||
query MetadataExport {
|
|
||||||
metadataExport
|
|
||||||
}
|
|
||||||
|
|
||||||
query MetadataScan($input: ScanMetadataInput!) {
|
|
||||||
metadataScan(input: $input)
|
|
||||||
}
|
|
||||||
|
|
||||||
query MetadataGenerate($input: GenerateMetadataInput!) {
|
|
||||||
metadataGenerate(input: $input)
|
|
||||||
}
|
|
||||||
|
|
||||||
query MetadataAutoTag($input: AutoTagMetadataInput!) {
|
|
||||||
metadataAutoTag(input: $input)
|
|
||||||
}
|
|
||||||
|
|
||||||
query MetadataClean {
|
|
||||||
metadataClean
|
|
||||||
}
|
|
||||||
|
|
||||||
query JobStatus {
|
query JobStatus {
|
||||||
jobStatus {
|
jobStatus {
|
||||||
progress
|
progress
|
||||||
@@ -29,7 +5,3 @@ query JobStatus {
|
|||||||
message
|
message
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
query StopJob {
|
|
||||||
stopJob
|
|
||||||
}
|
|
||||||
@@ -77,21 +77,7 @@ type Query {
|
|||||||
|
|
||||||
# Metadata
|
# Metadata
|
||||||
|
|
||||||
"""Start an import. Returns the job ID"""
|
|
||||||
metadataImport: String!
|
|
||||||
"""Start an export. Returns the job ID"""
|
|
||||||
metadataExport: String!
|
|
||||||
"""Start a scan. Returns the job ID"""
|
|
||||||
metadataScan(input: ScanMetadataInput!): String!
|
|
||||||
"""Start generating content. Returns the job ID"""
|
|
||||||
metadataGenerate(input: GenerateMetadataInput!): String!
|
|
||||||
"""Start auto-tagging. Returns the job ID"""
|
|
||||||
metadataAutoTag(input: AutoTagMetadataInput!): String!
|
|
||||||
"""Clean metadata. Returns the job ID"""
|
|
||||||
metadataClean: String!
|
|
||||||
|
|
||||||
jobStatus: MetadataUpdateStatus!
|
jobStatus: MetadataUpdateStatus!
|
||||||
stopJob: Boolean!
|
|
||||||
|
|
||||||
# Get everything
|
# Get everything
|
||||||
|
|
||||||
@@ -120,6 +106,9 @@ type Mutation {
|
|||||||
"""Resets the o-counter for a scene to 0. Returns the new value"""
|
"""Resets the o-counter for a scene to 0. Returns the new value"""
|
||||||
sceneResetO(id: ID!): Int!
|
sceneResetO(id: ID!): Int!
|
||||||
|
|
||||||
|
"""Generates screenshot at specified time in seconds. Leave empty to generate default screenshot"""
|
||||||
|
sceneGenerateScreenshot(id: ID!, at: Float): String!
|
||||||
|
|
||||||
sceneMarkerCreate(input: SceneMarkerCreateInput!): SceneMarker
|
sceneMarkerCreate(input: SceneMarkerCreateInput!): SceneMarker
|
||||||
sceneMarkerUpdate(input: SceneMarkerUpdateInput!): SceneMarker
|
sceneMarkerUpdate(input: SceneMarkerUpdateInput!): SceneMarker
|
||||||
sceneMarkerDestroy(id: ID!): Boolean!
|
sceneMarkerDestroy(id: ID!): Boolean!
|
||||||
@@ -143,6 +132,21 @@ type Mutation {
|
|||||||
"""Change general configuration options"""
|
"""Change general configuration options"""
|
||||||
configureGeneral(input: ConfigGeneralInput!): ConfigGeneralResult!
|
configureGeneral(input: ConfigGeneralInput!): ConfigGeneralResult!
|
||||||
configureInterface(input: ConfigInterfaceInput!): ConfigInterfaceResult!
|
configureInterface(input: ConfigInterfaceInput!): ConfigInterfaceResult!
|
||||||
|
|
||||||
|
"""Start an import. Returns the job ID"""
|
||||||
|
metadataImport: String!
|
||||||
|
"""Start an export. Returns the job ID"""
|
||||||
|
metadataExport: String!
|
||||||
|
"""Start a scan. Returns the job ID"""
|
||||||
|
metadataScan(input: ScanMetadataInput!): String!
|
||||||
|
"""Start generating content. Returns the job ID"""
|
||||||
|
metadataGenerate(input: GenerateMetadataInput!): String!
|
||||||
|
"""Start auto-tagging. Returns the job ID"""
|
||||||
|
metadataAutoTag(input: AutoTagMetadataInput!): String!
|
||||||
|
"""Clean metadata. Returns the job ID"""
|
||||||
|
metadataClean: String!
|
||||||
|
|
||||||
|
stopJob: Boolean!
|
||||||
}
|
}
|
||||||
|
|
||||||
type Subscription {
|
type Subscription {
|
||||||
|
|||||||
53
pkg/api/resolver_mutation_metadata.go
Normal file
53
pkg/api/resolver_mutation_metadata.go
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/stashapp/stash/pkg/manager"
|
||||||
|
"github.com/stashapp/stash/pkg/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (r *mutationResolver) MetadataScan(ctx context.Context, input models.ScanMetadataInput) (string, error) {
|
||||||
|
manager.GetInstance().Scan(input.UseFileMetadata)
|
||||||
|
return "todo", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *mutationResolver) MetadataImport(ctx context.Context) (string, error) {
|
||||||
|
manager.GetInstance().Import()
|
||||||
|
return "todo", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *mutationResolver) MetadataExport(ctx context.Context) (string, error) {
|
||||||
|
manager.GetInstance().Export()
|
||||||
|
return "todo", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *mutationResolver) MetadataGenerate(ctx context.Context, input models.GenerateMetadataInput) (string, error) {
|
||||||
|
manager.GetInstance().Generate(input.Sprites, input.Previews, input.Markers, input.Transcodes)
|
||||||
|
return "todo", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *mutationResolver) MetadataAutoTag(ctx context.Context, input models.AutoTagMetadataInput) (string, error) {
|
||||||
|
manager.GetInstance().AutoTag(input.Performers, input.Studios, input.Tags)
|
||||||
|
return "todo", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *mutationResolver) MetadataClean(ctx context.Context) (string, error) {
|
||||||
|
manager.GetInstance().Clean()
|
||||||
|
return "todo", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *mutationResolver) JobStatus(ctx context.Context) (*models.MetadataUpdateStatus, error) {
|
||||||
|
status := manager.GetInstance().Status
|
||||||
|
ret := models.MetadataUpdateStatus{
|
||||||
|
Progress: status.Progress,
|
||||||
|
Status: status.Status.String(),
|
||||||
|
Message: "",
|
||||||
|
}
|
||||||
|
|
||||||
|
return &ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *mutationResolver) StopJob(ctx context.Context) (bool, error) {
|
||||||
|
return manager.GetInstance().Status.Stop(), nil
|
||||||
|
}
|
||||||
@@ -500,3 +500,13 @@ func (r *mutationResolver) SceneResetO(ctx context.Context, id string) (int, err
|
|||||||
|
|
||||||
return newVal, nil
|
return newVal, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *mutationResolver) SceneGenerateScreenshot(ctx context.Context, id string, at *float64) (string, error) {
|
||||||
|
if at != nil {
|
||||||
|
manager.GetInstance().GenerateScreenshot(id, *at)
|
||||||
|
} else {
|
||||||
|
manager.GetInstance().GenerateDefaultScreenshot(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
return "todo", nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,36 +7,6 @@ import (
|
|||||||
"github.com/stashapp/stash/pkg/models"
|
"github.com/stashapp/stash/pkg/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *queryResolver) MetadataScan(ctx context.Context, input models.ScanMetadataInput) (string, error) {
|
|
||||||
manager.GetInstance().Scan(input.UseFileMetadata)
|
|
||||||
return "todo", nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *queryResolver) MetadataImport(ctx context.Context) (string, error) {
|
|
||||||
manager.GetInstance().Import()
|
|
||||||
return "todo", nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *queryResolver) MetadataExport(ctx context.Context) (string, error) {
|
|
||||||
manager.GetInstance().Export()
|
|
||||||
return "todo", nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *queryResolver) MetadataGenerate(ctx context.Context, input models.GenerateMetadataInput) (string, error) {
|
|
||||||
manager.GetInstance().Generate(input.Sprites, input.Previews, input.Markers, input.Transcodes)
|
|
||||||
return "todo", nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *queryResolver) MetadataAutoTag(ctx context.Context, input models.AutoTagMetadataInput) (string, error) {
|
|
||||||
manager.GetInstance().AutoTag(input.Performers, input.Studios, input.Tags)
|
|
||||||
return "todo", nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *queryResolver) MetadataClean(ctx context.Context) (string, error) {
|
|
||||||
manager.GetInstance().Clean()
|
|
||||||
return "todo", nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *queryResolver) JobStatus(ctx context.Context) (*models.MetadataUpdateStatus, error) {
|
func (r *queryResolver) JobStatus(ctx context.Context) (*models.MetadataUpdateStatus, error) {
|
||||||
status := manager.GetInstance().Status
|
status := manager.GetInstance().Status
|
||||||
ret := models.MetadataUpdateStatus{
|
ret := models.MetadataUpdateStatus{
|
||||||
@@ -47,7 +17,3 @@ func (r *queryResolver) JobStatus(ctx context.Context) (*models.MetadataUpdateSt
|
|||||||
|
|
||||||
return &ret, nil
|
return &ret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *queryResolver) StopJob(ctx context.Context) (bool, error) {
|
|
||||||
return manager.GetInstance().Status.Stop(), nil
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ type ScreenshotOptions struct {
|
|||||||
Verbosity string
|
Verbosity string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) Screenshot(probeResult VideoFile, options ScreenshotOptions) {
|
func (e *Encoder) Screenshot(probeResult VideoFile, options ScreenshotOptions) error {
|
||||||
if options.Verbosity == "" {
|
if options.Verbosity == "" {
|
||||||
options.Verbosity = "error"
|
options.Verbosity = "error"
|
||||||
}
|
}
|
||||||
@@ -28,5 +28,7 @@ func (e *Encoder) Screenshot(probeResult VideoFile, options ScreenshotOptions) {
|
|||||||
"-f", "image2",
|
"-f", "image2",
|
||||||
options.OutputPath,
|
options.OutputPath,
|
||||||
}
|
}
|
||||||
_, _ = e.run(probeResult, args)
|
_, err := e.run(probeResult, args)
|
||||||
|
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -216,6 +216,55 @@ func (s *singleton) Generate(sprites bool, previews bool, markers bool, transcod
|
|||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *singleton) GenerateDefaultScreenshot(sceneId string) {
|
||||||
|
s.generateScreenshot(sceneId, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *singleton) GenerateScreenshot(sceneId string, at float64) {
|
||||||
|
s.generateScreenshot(sceneId, &at)
|
||||||
|
}
|
||||||
|
|
||||||
|
// generate default screenshot if at is nil
|
||||||
|
func (s *singleton) generateScreenshot(sceneId string, at *float64) {
|
||||||
|
if s.Status.Status != Idle {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s.Status.SetStatus(Generate)
|
||||||
|
s.Status.indefiniteProgress()
|
||||||
|
|
||||||
|
qb := models.NewSceneQueryBuilder()
|
||||||
|
instance.Paths.Generated.EnsureTmpDir()
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
defer s.returnToIdleState()
|
||||||
|
|
||||||
|
sceneIdInt, err := strconv.Atoi(sceneId)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("Error parsing scene id %s: %s", sceneId, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
scene, err := qb.Find(sceneIdInt)
|
||||||
|
if err != nil || scene == nil {
|
||||||
|
logger.Errorf("failed to get scene for generate")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
task := GenerateScreenshotTask{
|
||||||
|
Scene: *scene,
|
||||||
|
ScreenshotAt: at,
|
||||||
|
}
|
||||||
|
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
wg.Add(1)
|
||||||
|
go task.Start(&wg)
|
||||||
|
|
||||||
|
wg.Wait()
|
||||||
|
|
||||||
|
logger.Infof("Generate finished")
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
func (s *singleton) AutoTag(performerIds []string, studioIds []string, tagIds []string) {
|
func (s *singleton) AutoTag(performerIds []string, studioIds []string, tagIds []string) {
|
||||||
if s.Status.Status != Idle {
|
if s.Status.Status != Idle {
|
||||||
return
|
return
|
||||||
|
|||||||
16
pkg/manager/screenshot.go
Normal file
16
pkg/manager/screenshot.go
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package manager
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/stashapp/stash/pkg/ffmpeg"
|
||||||
|
)
|
||||||
|
|
||||||
|
func makeScreenshot(probeResult ffmpeg.VideoFile, outputPath string, quality int, width int, time float64) {
|
||||||
|
encoder := ffmpeg.NewEncoder(instance.FFMPEGPath)
|
||||||
|
options := ffmpeg.ScreenshotOptions{
|
||||||
|
OutputPath: outputPath,
|
||||||
|
Quality: quality,
|
||||||
|
Time: time,
|
||||||
|
Width: width,
|
||||||
|
}
|
||||||
|
encoder.Screenshot(probeResult, options)
|
||||||
|
}
|
||||||
84
pkg/manager/task_generate_screenshot.go
Normal file
84
pkg/manager/task_generate_screenshot.go
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
package manager
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"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"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GenerateScreenshotTask struct {
|
||||||
|
Scene models.Scene
|
||||||
|
ScreenshotAt *float64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *GenerateScreenshotTask) Start(wg *sync.WaitGroup) {
|
||||||
|
defer wg.Done()
|
||||||
|
|
||||||
|
scenePath := t.Scene.Path
|
||||||
|
probeResult, err := ffmpeg.NewVideoFile(instance.FFProbePath, scenePath)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
logger.Error(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var at float64
|
||||||
|
if t.ScreenshotAt == nil {
|
||||||
|
at = float64(probeResult.Duration) * 0.2
|
||||||
|
} else {
|
||||||
|
at = *t.ScreenshotAt
|
||||||
|
}
|
||||||
|
|
||||||
|
checksum := t.Scene.Checksum
|
||||||
|
normalPath := instance.Paths.Scene.GetScreenshotPath(checksum)
|
||||||
|
|
||||||
|
// we'll generate the screenshot, grab the generated data and set it
|
||||||
|
// in the database. We'll use SetSceneScreenshot to set the data
|
||||||
|
// which also generates the thumbnail
|
||||||
|
|
||||||
|
logger.Debugf("Creating screenshot for %s", scenePath)
|
||||||
|
makeScreenshot(*probeResult, normalPath, 2, probeResult.Width, at)
|
||||||
|
|
||||||
|
f, err := os.Open(normalPath)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("Error reading screenshot: %s", err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
coverImageData, err := ioutil.ReadAll(f)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("Error reading screenshot: %s", err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := context.TODO()
|
||||||
|
tx := database.DB.MustBeginTx(ctx, nil)
|
||||||
|
|
||||||
|
qb := models.NewSceneQueryBuilder()
|
||||||
|
updatedTime := time.Now()
|
||||||
|
updatedScene := models.ScenePartial{
|
||||||
|
ID: t.Scene.ID,
|
||||||
|
UpdatedAt: &models.SQLiteTimestamp{Timestamp: updatedTime},
|
||||||
|
}
|
||||||
|
|
||||||
|
updatedScene.Cover = &coverImageData
|
||||||
|
err = SetSceneScreenshot(t.Scene.Checksum, coverImageData)
|
||||||
|
_, err = qb.Update(updatedScene, tx)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("Error setting screenshot: %s", err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := tx.Commit(); err != nil {
|
||||||
|
logger.Errorf("Error setting screenshot: %s", err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -177,28 +177,19 @@ func (t *ScanTask) makeScreenshots(probeResult *ffmpeg.VideoFile, checksum strin
|
|||||||
logger.Infof("Regenerating images for %s", t.FilePath)
|
logger.Infof("Regenerating images for %s", t.FilePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
at := float64(probeResult.Duration) * 0.2
|
||||||
|
|
||||||
if !thumbExists {
|
if !thumbExists {
|
||||||
logger.Debugf("Creating thumbnail for %s", t.FilePath)
|
logger.Debugf("Creating thumbnail for %s", t.FilePath)
|
||||||
t.makeScreenshot(*probeResult, thumbPath, 5, 320)
|
makeScreenshot(*probeResult, thumbPath, 5, 320, at)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !normalExists {
|
if !normalExists {
|
||||||
logger.Debugf("Creating screenshot for %s", t.FilePath)
|
logger.Debugf("Creating screenshot for %s", t.FilePath)
|
||||||
t.makeScreenshot(*probeResult, normalPath, 2, probeResult.Width)
|
makeScreenshot(*probeResult, normalPath, 2, probeResult.Width, at)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *ScanTask) makeScreenshot(probeResult ffmpeg.VideoFile, outputPath string, quality int, width int) {
|
|
||||||
encoder := ffmpeg.NewEncoder(instance.FFMPEGPath)
|
|
||||||
options := ffmpeg.ScreenshotOptions{
|
|
||||||
OutputPath: outputPath,
|
|
||||||
Quality: quality,
|
|
||||||
Time: float64(probeResult.Duration) * 0.2,
|
|
||||||
Width: width,
|
|
||||||
}
|
|
||||||
encoder.Screenshot(probeResult, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *ScanTask) calculateChecksum() (string, error) {
|
func (t *ScanTask) calculateChecksum() (string, error) {
|
||||||
logger.Infof("%s not found. Calculating checksum...", t.FilePath)
|
logger.Infof("%s not found. Calculating checksum...", t.FilePath)
|
||||||
checksum, err := utils.MD5FromFilePath(t.FilePath)
|
checksum, err := utils.MD5FromFilePath(t.FilePath)
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ export const PerformerOperationsPanel: React.FC<IPerformerOperationsProps> = ({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
await StashService.queryMetadataAutoTag({ performers: [performer.id] });
|
await StashService.mutateMetadataAutoTag({ performers: [performer.id] });
|
||||||
Toast.success({ content: "Started auto tagging" });
|
Toast.success({ content: "Started auto tagging" });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Toast.error(e);
|
Toast.error(e);
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import { SceneFileInfoPanel } from "./SceneFileInfoPanel";
|
|||||||
import { SceneEditPanel } from "./SceneEditPanel";
|
import { SceneEditPanel } from "./SceneEditPanel";
|
||||||
import { SceneDetailPanel } from "./SceneDetailPanel";
|
import { SceneDetailPanel } from "./SceneDetailPanel";
|
||||||
import { OCounterButton } from "./OCounterButton";
|
import { OCounterButton } from "./OCounterButton";
|
||||||
|
import { SceneOperationsPanel } from "./SceneOperationsPanel";
|
||||||
|
|
||||||
export const Scene: React.FC = () => {
|
export const Scene: React.FC = () => {
|
||||||
const { id = "new" } = useParams();
|
const { id = "new" } = useParams();
|
||||||
@@ -144,6 +145,11 @@ export const Scene: React.FC = () => {
|
|||||||
onDelete={() => history.push("/scenes")}
|
onDelete={() => history.push("/scenes")}
|
||||||
/>
|
/>
|
||||||
</Tab>
|
</Tab>
|
||||||
|
<Tab eventKey="scene-operations-panel" title="Operations">
|
||||||
|
<SceneOperationsPanel
|
||||||
|
scene={scene}
|
||||||
|
/>
|
||||||
|
</Tab>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
import { Button } from "react-bootstrap";
|
||||||
|
import React, { FunctionComponent } from "react";
|
||||||
|
import * as GQL from "src/core/generated-graphql";
|
||||||
|
import { StashService } from "src/core/StashService";
|
||||||
|
import { useToast } from "src/hooks";
|
||||||
|
import { JWUtils } from "src/utils";
|
||||||
|
|
||||||
|
interface IOperationsPanelProps {
|
||||||
|
scene: GQL.SceneDataFragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const SceneOperationsPanel: FunctionComponent<IOperationsPanelProps> = (props: IOperationsPanelProps) => {
|
||||||
|
const Toast = useToast();
|
||||||
|
const [generateScreenshot] = StashService.useSceneGenerateScreenshot();
|
||||||
|
|
||||||
|
async function onGenerateScreenshot(at?: number) {
|
||||||
|
await generateScreenshot({
|
||||||
|
variables: {
|
||||||
|
id: props.scene.id,
|
||||||
|
at: at
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Toast.success({ content: "Generating screenshot" });
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Button className="edit-button" onClick={() => onGenerateScreenshot(JWUtils.getPlayer().getPosition())}>
|
||||||
|
Generate thumbnail from current
|
||||||
|
</Button>
|
||||||
|
<Button className="edit-button" onClick={() => onGenerateScreenshot()}>
|
||||||
|
Generate default thumbnail
|
||||||
|
</Button>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -12,7 +12,7 @@ export const GenerateButton: React.FC = () => {
|
|||||||
|
|
||||||
async function onGenerate() {
|
async function onGenerate() {
|
||||||
try {
|
try {
|
||||||
await StashService.queryMetadataGenerate({
|
await StashService.mutateMetadataGenerate({
|
||||||
sprites,
|
sprites,
|
||||||
previews,
|
previews,
|
||||||
markers,
|
markers,
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ export const SettingsTasksPanel: React.FC = () => {
|
|||||||
|
|
||||||
function onImport() {
|
function onImport() {
|
||||||
setIsImportAlertOpen(false);
|
setIsImportAlertOpen(false);
|
||||||
StashService.queryMetadataImport().then(() => {
|
StashService.mutateMetadataImport().then(() => {
|
||||||
jobStatus.refetch();
|
jobStatus.refetch();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -91,7 +91,7 @@ export const SettingsTasksPanel: React.FC = () => {
|
|||||||
|
|
||||||
function onClean() {
|
function onClean() {
|
||||||
setIsCleanAlertOpen(false);
|
setIsCleanAlertOpen(false);
|
||||||
StashService.queryMetadataClean().then(() => {
|
StashService.mutateMetadataClean().then(() => {
|
||||||
jobStatus.refetch();
|
jobStatus.refetch();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -115,7 +115,7 @@ export const SettingsTasksPanel: React.FC = () => {
|
|||||||
|
|
||||||
async function onScan() {
|
async function onScan() {
|
||||||
try {
|
try {
|
||||||
await StashService.queryMetadataScan({ useFileMetadata });
|
await StashService.mutateMetadataScan({ useFileMetadata });
|
||||||
Toast.success({ content: "Started scan" });
|
Toast.success({ content: "Started scan" });
|
||||||
jobStatus.refetch();
|
jobStatus.refetch();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -134,7 +134,7 @@ export const SettingsTasksPanel: React.FC = () => {
|
|||||||
|
|
||||||
async function onAutoTag() {
|
async function onAutoTag() {
|
||||||
try {
|
try {
|
||||||
await StashService.queryMetadataAutoTag(getAutoTagInput());
|
await StashService.mutateMetadataAutoTag(getAutoTagInput());
|
||||||
Toast.success({ content: "Started auto tagging" });
|
Toast.success({ content: "Started auto tagging" });
|
||||||
jobStatus.refetch();
|
jobStatus.refetch();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -153,7 +153,7 @@ export const SettingsTasksPanel: React.FC = () => {
|
|||||||
id="stop"
|
id="stop"
|
||||||
variant="danger"
|
variant="danger"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
StashService.queryStopJob().then(() => jobStatus.refetch())
|
StashService.mutateStopJob().then(() => jobStatus.refetch())
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
Stop
|
Stop
|
||||||
@@ -277,7 +277,7 @@ export const SettingsTasksPanel: React.FC = () => {
|
|||||||
variant="secondary"
|
variant="secondary"
|
||||||
type="submit"
|
type="submit"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
StashService.queryMetadataExport().then(() => {
|
StashService.mutateMetadataExport().then(() => {
|
||||||
jobStatus.refetch();
|
jobStatus.refetch();
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ export const Studio: React.FC = () => {
|
|||||||
async function onAutoTag() {
|
async function onAutoTag() {
|
||||||
if (!studio.id) return;
|
if (!studio.id) return;
|
||||||
try {
|
try {
|
||||||
await StashService.queryMetadataAutoTag({ studios: [studio.id] });
|
await StashService.mutateMetadataAutoTag({ studios: [studio.id] });
|
||||||
Toast.success({ content: "Started auto tagging" });
|
Toast.success({ content: "Started auto tagging" });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Toast.error(e);
|
Toast.error(e);
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ export const TagList: React.FC = () => {
|
|||||||
async function onAutoTag(tag: GQL.TagDataFragment) {
|
async function onAutoTag(tag: GQL.TagDataFragment) {
|
||||||
if (!tag) return;
|
if (!tag) return;
|
||||||
try {
|
try {
|
||||||
await StashService.queryMetadataAutoTag({ tags: [tag.id] });
|
await StashService.mutateMetadataAutoTag({ tags: [tag.id] });
|
||||||
Toast.success({ content: "Started auto tagging" });
|
Toast.success({ content: "Started auto tagging" });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Toast.error(e);
|
Toast.error(e);
|
||||||
|
|||||||
@@ -407,6 +407,12 @@ export class StashService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static useSceneGenerateScreenshot() {
|
||||||
|
return GQL.useSceneGenerateScreenshotMutation({
|
||||||
|
update: () => StashService.invalidateQueries(["findScenes"]),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private static studioMutationImpactedQueries = [
|
private static studioMutationImpactedQueries = [
|
||||||
"findStudios",
|
"findStudios",
|
||||||
"findScenes",
|
"findScenes",
|
||||||
@@ -506,10 +512,9 @@ export class StashService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static queryStopJob() {
|
public static mutateStopJob() {
|
||||||
return StashService.client.query<GQL.StopJobQuery>({
|
return StashService.client.mutate<GQL.StopJobMutation>({
|
||||||
query: GQL.StopJobDocument,
|
mutation: GQL.StopJobDocument,
|
||||||
fetchPolicy: "network-only"
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -566,48 +571,42 @@ export class StashService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static queryMetadataScan(input: GQL.ScanMetadataInput) {
|
public static mutateMetadataScan(input: GQL.ScanMetadataInput) {
|
||||||
return StashService.client.query<GQL.MetadataScanQuery>({
|
return StashService.client.mutate<GQL.MetadataScanMutation>({
|
||||||
query: GQL.MetadataScanDocument,
|
mutation: GQL.MetadataScanDocument,
|
||||||
variables: { input },
|
variables: { input },
|
||||||
fetchPolicy: "network-only"
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static queryMetadataAutoTag(input: GQL.AutoTagMetadataInput) {
|
public static mutateMetadataAutoTag(input: GQL.AutoTagMetadataInput) {
|
||||||
return StashService.client.query<GQL.MetadataAutoTagQuery>({
|
return StashService.client.mutate<GQL.MetadataAutoTagMutation>({
|
||||||
query: GQL.MetadataAutoTagDocument,
|
mutation: GQL.MetadataAutoTagDocument,
|
||||||
variables: { input },
|
variables: { input },
|
||||||
fetchPolicy: "network-only"
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static queryMetadataGenerate(input: GQL.GenerateMetadataInput) {
|
public static mutateMetadataGenerate(input: GQL.GenerateMetadataInput) {
|
||||||
return StashService.client.query<GQL.MetadataGenerateQuery>({
|
return StashService.client.mutate<GQL.MetadataGenerateMutation>({
|
||||||
query: GQL.MetadataGenerateDocument,
|
mutation: GQL.MetadataGenerateDocument,
|
||||||
variables: { input },
|
variables: { input },
|
||||||
fetchPolicy: "network-only"
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static queryMetadataClean() {
|
public static mutateMetadataClean() {
|
||||||
return StashService.client.query<GQL.MetadataCleanQuery>({
|
return StashService.client.mutate<GQL.MetadataCleanMutation>({
|
||||||
query: GQL.MetadataCleanDocument,
|
mutation: GQL.MetadataCleanDocument,
|
||||||
fetchPolicy: "network-only"
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static queryMetadataExport() {
|
public static mutateMetadataExport() {
|
||||||
return StashService.client.query<GQL.MetadataExportQuery>({
|
return StashService.client.mutate<GQL.MetadataExportMutation>({
|
||||||
query: GQL.MetadataExportDocument,
|
mutation: GQL.MetadataExportDocument,
|
||||||
fetchPolicy: "network-only"
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static queryMetadataImport() {
|
public static mutateMetadataImport() {
|
||||||
return StashService.client.query<GQL.MetadataImportQuery>({
|
return StashService.client.mutate<GQL.MetadataImportMutation>({
|
||||||
query: GQL.MetadataImportDocument,
|
mutation: GQL.MetadataImportDocument,
|
||||||
fetchPolicy: "network-only"
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ export const GenerateButton: FunctionComponent<IProps> = () => {
|
|||||||
|
|
||||||
async function onGenerate() {
|
async function onGenerate() {
|
||||||
try {
|
try {
|
||||||
await StashService.queryMetadataGenerate({sprites, previews, markers, transcodes});
|
await StashService.mutateMetadataGenerate({sprites, previews, markers, transcodes});
|
||||||
ToastUtils.success("Started generating");
|
ToastUtils.success("Started generating");
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
ErrorUtils.handle(e);
|
ErrorUtils.handle(e);
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ export const SettingsTasksPanel: FunctionComponent<IProps> = (props: IProps) =>
|
|||||||
|
|
||||||
function onImport() {
|
function onImport() {
|
||||||
setIsImportAlertOpen(false);
|
setIsImportAlertOpen(false);
|
||||||
StashService.queryMetadataImport().then(() => { jobStatus.refetch()});
|
StashService.mutateMetadataImport().then(() => { jobStatus.refetch()});
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderImportAlert() {
|
function renderImportAlert() {
|
||||||
@@ -102,7 +102,7 @@ export const SettingsTasksPanel: FunctionComponent<IProps> = (props: IProps) =>
|
|||||||
|
|
||||||
function onClean() {
|
function onClean() {
|
||||||
setIsCleanAlertOpen(false);
|
setIsCleanAlertOpen(false);
|
||||||
StashService.queryMetadataClean().then(() => { jobStatus.refetch()});
|
StashService.mutateMetadataClean().then(() => { jobStatus.refetch()});
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderCleanAlert() {
|
function renderCleanAlert() {
|
||||||
@@ -127,7 +127,7 @@ export const SettingsTasksPanel: FunctionComponent<IProps> = (props: IProps) =>
|
|||||||
|
|
||||||
async function onScan() {
|
async function onScan() {
|
||||||
try {
|
try {
|
||||||
await StashService.queryMetadataScan({useFileMetadata: useFileMetadata});
|
await StashService.mutateMetadataScan({useFileMetadata: useFileMetadata});
|
||||||
ToastUtils.success("Started scan");
|
ToastUtils.success("Started scan");
|
||||||
jobStatus.refetch();
|
jobStatus.refetch();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -146,7 +146,7 @@ export const SettingsTasksPanel: FunctionComponent<IProps> = (props: IProps) =>
|
|||||||
|
|
||||||
async function onAutoTag() {
|
async function onAutoTag() {
|
||||||
try {
|
try {
|
||||||
await StashService.queryMetadataAutoTag(getAutoTagInput());
|
await StashService.mutateMetadataAutoTag(getAutoTagInput());
|
||||||
ToastUtils.success("Started auto tagging");
|
ToastUtils.success("Started auto tagging");
|
||||||
jobStatus.refetch();
|
jobStatus.refetch();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -162,7 +162,7 @@ export const SettingsTasksPanel: FunctionComponent<IProps> = (props: IProps) =>
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<Button id="stop" text="Stop" intent="danger" onClick={() => StashService.queryStopJob().then(() => jobStatus.refetch())} />
|
<Button id="stop" text="Stop" intent="danger" onClick={() => StashService.mutateStopJob().then(() => jobStatus.refetch())} />
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
@@ -256,7 +256,7 @@ export const SettingsTasksPanel: FunctionComponent<IProps> = (props: IProps) =>
|
|||||||
labelFor="export"
|
labelFor="export"
|
||||||
inline={true}
|
inline={true}
|
||||||
>
|
>
|
||||||
<Button id="export" text="Export" onClick={() => StashService.queryMetadataExport().then(() => { jobStatus.refetch()})} />
|
<Button id="export" text="Export" onClick={() => StashService.mutateMetadataExport().then(() => { jobStatus.refetch()})} />
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|
||||||
<FormGroup
|
<FormGroup
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ export const Studio: FunctionComponent<IProps> = (props: IProps) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
await StashService.queryMetadataAutoTag({ studios: [studio.id]});
|
await StashService.mutateMetadataAutoTag({ studios: [studio.id]});
|
||||||
ToastUtils.success("Started auto tagging");
|
ToastUtils.success("Started auto tagging");
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
ErrorUtils.handle(e);
|
ErrorUtils.handle(e);
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ export const TagList: FunctionComponent<IProps> = (props: IProps) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
await StashService.queryMetadataAutoTag({ tags: [tag.id]});
|
await StashService.mutateMetadataAutoTag({ tags: [tag.id]});
|
||||||
ToastUtils.success("Started auto tagging");
|
ToastUtils.success("Started auto tagging");
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
ErrorUtils.handle(e);
|
ErrorUtils.handle(e);
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ export const PerformerOperationsPanel: FunctionComponent<IPerformerOperationsPro
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
await StashService.queryMetadataAutoTag({ performers: [props.performer.id]});
|
await StashService.mutateMetadataAutoTag({ performers: [props.performer.id]});
|
||||||
ToastUtils.success("Started auto tagging");
|
ToastUtils.success("Started auto tagging");
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
ErrorUtils.handle(e);
|
ErrorUtils.handle(e);
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import { ScenePerformerPanel } from "./ScenePerformerPanel";
|
|||||||
import { SceneMoviePanel } from "./SceneMoviePanel";
|
import { SceneMoviePanel } from "./SceneMoviePanel";
|
||||||
import { ErrorUtils } from "../../../utils/errors";
|
import { ErrorUtils } from "../../../utils/errors";
|
||||||
import { IOCounterButtonProps, OCounterButton } from "../OCounterButton";
|
import { IOCounterButtonProps, OCounterButton } from "../OCounterButton";
|
||||||
|
import { SceneOperationsPanel } from "./SceneOperationsPanel";
|
||||||
|
|
||||||
interface ISceneProps extends IBaseProps {}
|
interface ISceneProps extends IBaseProps {}
|
||||||
|
|
||||||
@@ -160,6 +161,14 @@ export const Scene: FunctionComponent<ISceneProps> = (props: ISceneProps) => {
|
|||||||
onDelete={() => props.history.push("/scenes")}
|
onDelete={() => props.history.push("/scenes")}
|
||||||
/>}
|
/>}
|
||||||
/>
|
/>
|
||||||
|
<Tab
|
||||||
|
id="scene-operations-panel"
|
||||||
|
title="Operations"
|
||||||
|
panel={
|
||||||
|
<SceneOperationsPanel
|
||||||
|
scene={modifiedScene}
|
||||||
|
/>}
|
||||||
|
/>
|
||||||
|
|
||||||
<Tabs.Expander />
|
<Tabs.Expander />
|
||||||
<OCounterButton
|
<OCounterButton
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
import {
|
||||||
|
Button,
|
||||||
|
} from "@blueprintjs/core";
|
||||||
|
import React, { FunctionComponent } from "react";
|
||||||
|
import * as GQL from "../../../core/generated-graphql";
|
||||||
|
import { StashService } from "../../../core/StashService";
|
||||||
|
import { SceneHelpers } from "../helpers";
|
||||||
|
import { ToastUtils } from "../../../utils/toasts";
|
||||||
|
|
||||||
|
interface IOperationsPanelProps {
|
||||||
|
scene: GQL.SceneDataFragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const SceneOperationsPanel: FunctionComponent<IOperationsPanelProps> = (props: IOperationsPanelProps) => {
|
||||||
|
|
||||||
|
const jwplayer = SceneHelpers.getPlayer();
|
||||||
|
const generateScreenshot = StashService.useSceneGenerateScreenshot();
|
||||||
|
|
||||||
|
async function onGenerateScreenshot() {
|
||||||
|
let position = jwplayer.getPosition();
|
||||||
|
|
||||||
|
await generateScreenshot({
|
||||||
|
variables: {
|
||||||
|
id: props.scene.id,
|
||||||
|
at: position
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ToastUtils.success("Generating screenshot");
|
||||||
|
}
|
||||||
|
|
||||||
|
async function onGenerateDefaultScreenshot() {
|
||||||
|
await generateScreenshot({
|
||||||
|
variables: {
|
||||||
|
id: props.scene.id,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ToastUtils.success("Generating screenshot");
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Button className="edit-button" text="Generate thumbnail from current" onClick={() => onGenerateScreenshot()}/>
|
||||||
|
<Button className="edit-button" text="Generate default thumbnail" onClick={() => onGenerateDefaultScreenshot()}/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
@@ -355,6 +355,12 @@ export class StashService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static useSceneGenerateScreenshot() {
|
||||||
|
return GQL.useSceneGenerateScreenshot({
|
||||||
|
update: () => StashService.invalidateQueries(["findScenes"]),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private static studioMutationImpactedQueries = [
|
private static studioMutationImpactedQueries = [
|
||||||
"findStudios",
|
"findStudios",
|
||||||
"findScenes",
|
"findScenes",
|
||||||
@@ -467,10 +473,9 @@ export class StashService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static queryStopJob() {
|
public static mutateStopJob() {
|
||||||
return StashService.client.query<GQL.StopJobQuery>({
|
return StashService.client.mutate<GQL.StopJobMutation>({
|
||||||
query: GQL.StopJobDocument,
|
mutation: GQL.StopJobDocument,
|
||||||
fetchPolicy: "network-only",
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -521,48 +526,42 @@ export class StashService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static queryMetadataScan(input: GQL.ScanMetadataInput) {
|
public static mutateMetadataScan(input: GQL.ScanMetadataInput) {
|
||||||
return StashService.client.query<GQL.MetadataScanQuery>({
|
return StashService.client.mutate<GQL.MetadataScanMutation>({
|
||||||
query: GQL.MetadataScanDocument,
|
mutation: GQL.MetadataScanDocument,
|
||||||
variables: { input },
|
variables: { input },
|
||||||
fetchPolicy: "network-only",
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static queryMetadataAutoTag(input: GQL.AutoTagMetadataInput) {
|
public static mutateMetadataAutoTag(input: GQL.AutoTagMetadataInput) {
|
||||||
return StashService.client.query<GQL.MetadataAutoTagQuery>({
|
return StashService.client.mutate<GQL.MetadataAutoTagMutation>({
|
||||||
query: GQL.MetadataAutoTagDocument,
|
mutation: GQL.MetadataAutoTagDocument,
|
||||||
variables: { input },
|
variables: { input },
|
||||||
fetchPolicy: "network-only",
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static queryMetadataGenerate(input: GQL.GenerateMetadataInput) {
|
public static mutateMetadataGenerate(input: GQL.GenerateMetadataInput) {
|
||||||
return StashService.client.query<GQL.MetadataGenerateQuery>({
|
return StashService.client.mutate<GQL.MetadataGenerateMutation>({
|
||||||
query: GQL.MetadataGenerateDocument,
|
mutation: GQL.MetadataGenerateDocument,
|
||||||
variables: { input },
|
variables: { input },
|
||||||
fetchPolicy: "network-only",
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static queryMetadataClean() {
|
public static mutateMetadataClean() {
|
||||||
return StashService.client.query<GQL.MetadataCleanQuery>({
|
return StashService.client.mutate<GQL.MetadataCleanMutation>({
|
||||||
query: GQL.MetadataCleanDocument,
|
mutation: GQL.MetadataCleanDocument,
|
||||||
fetchPolicy: "network-only",
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static queryMetadataExport() {
|
public static mutateMetadataExport() {
|
||||||
return StashService.client.query<GQL.MetadataExportQuery>({
|
return StashService.client.mutate<GQL.MetadataExportMutation>({
|
||||||
query: GQL.MetadataExportDocument,
|
mutation: GQL.MetadataExportDocument,
|
||||||
fetchPolicy: "network-only",
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static queryMetadataImport() {
|
public static mutateMetadataImport() {
|
||||||
return StashService.client.query<GQL.MetadataImportQuery>({
|
return StashService.client.mutate<GQL.MetadataImportMutation>({
|
||||||
query: GQL.MetadataImportDocument,
|
mutation: GQL.MetadataImportDocument,
|
||||||
fetchPolicy: "network-only",
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user