Correct Stash box endpoint inputs (#4924)

* Use stashbox endpoint instead of index
* Update UI to not use deprecated fields
This commit is contained in:
WithoutPants
2024-06-11 13:14:12 +10:00
committed by GitHub
parent 94a978d063
commit ed057c971f
17 changed files with 234 additions and 185 deletions

View File

@@ -128,7 +128,7 @@ input ScraperSourceInput {
stash_box_index: Int @deprecated(reason: "use stash_box_endpoint") stash_box_index: Int @deprecated(reason: "use stash_box_endpoint")
"Stash-box endpoint" "Stash-box endpoint"
stash_box_endpoint: String stash_box_endpoint: String
"Scraper ID to scrape with. Should be unset if stash_box_index is set" "Scraper ID to scrape with. Should be unset if stash_box_endpoint/stash_box_index is set"
scraper_id: ID scraper_id: ID
} }
@@ -137,7 +137,7 @@ type ScraperSource {
stash_box_index: Int @deprecated(reason: "use stash_box_endpoint") stash_box_index: Int @deprecated(reason: "use stash_box_endpoint")
"Stash-box endpoint" "Stash-box endpoint"
stash_box_endpoint: String stash_box_endpoint: String
"Scraper ID to scrape with. Should be unset if stash_box_index is set" "Scraper ID to scrape with. Should be unset if stash_box_endpoint/stash_box_index is set"
scraper_id: ID scraper_id: ID
} }
@@ -196,7 +196,9 @@ input ScrapeSingleMovieInput {
input StashBoxSceneQueryInput { input StashBoxSceneQueryInput {
"Index of the configured stash-box instance to use" "Index of the configured stash-box instance to use"
stash_box_index: Int! stash_box_index: Int @deprecated(reason: "use stash_box_endpoint")
"Endpoint of the stash-box instance to use"
stash_box_endpoint: String
"Instructs query by scene fingerprints" "Instructs query by scene fingerprints"
scene_ids: [ID!] scene_ids: [ID!]
"Query by query string" "Query by query string"
@@ -205,7 +207,9 @@ input StashBoxSceneQueryInput {
input StashBoxPerformerQueryInput { input StashBoxPerformerQueryInput {
"Index of the configured stash-box instance to use" "Index of the configured stash-box instance to use"
stash_box_index: Int! stash_box_index: Int @deprecated(reason: "use stash_box_endpoint")
"Endpoint of the stash-box instance to use"
stash_box_endpoint: String
"Instructs query by scene fingerprints" "Instructs query by scene fingerprints"
performer_ids: [ID!] performer_ids: [ID!]
"Query by query string" "Query by query string"
@@ -226,7 +230,9 @@ type StashBoxFingerprint {
"If neither ids nor names are set, tag all items" "If neither ids nor names are set, tag all items"
input StashBoxBatchTagInput { input StashBoxBatchTagInput {
"Stash endpoint to use for the tagging" "Stash endpoint to use for the tagging"
endpoint: Int! endpoint: Int @deprecated(reason: "use stash_box_endpoint")
"Endpoint of the stash-box instance to use"
stash_box_endpoint: String
"Fields to exclude when executing the tagging" "Fields to exclude when executing the tagging"
exclude_fields: [String!] exclude_fields: [String!]
"Refresh items already tagged by StashBox if true. Only tag items with no StashBox tagging if false" "Refresh items already tagged by StashBox if true. Only tag items with no StashBox tagging if false"

View File

@@ -22,10 +22,12 @@ input StashIDInput {
input StashBoxFingerprintSubmissionInput { input StashBoxFingerprintSubmissionInput {
scene_ids: [String!]! scene_ids: [String!]!
stash_box_index: Int! stash_box_index: Int @deprecated(reason: "use stash_box_endpoint")
stash_box_endpoint: String
} }
input StashBoxDraftSubmissionInput { input StashBoxDraftSubmissionInput {
id: String! id: String!
stash_box_index: Int! stash_box_index: Int @deprecated(reason: "use stash_box_endpoint")
stash_box_endpoint: String
} }

View File

@@ -6,41 +6,46 @@ import (
"strconv" "strconv"
"github.com/stashapp/stash/internal/manager" "github.com/stashapp/stash/internal/manager"
"github.com/stashapp/stash/internal/manager/config"
"github.com/stashapp/stash/pkg/logger" "github.com/stashapp/stash/pkg/logger"
"github.com/stashapp/stash/pkg/scraper/stashbox"
) )
func (r *mutationResolver) SubmitStashBoxFingerprints(ctx context.Context, input StashBoxFingerprintSubmissionInput) (bool, error) { func (r *mutationResolver) SubmitStashBoxFingerprints(ctx context.Context, input StashBoxFingerprintSubmissionInput) (bool, error) {
boxes := config.GetInstance().GetStashBoxes() b, err := resolveStashBox(input.StashBoxIndex, input.StashBoxEndpoint)
if err != nil {
if input.StashBoxIndex < 0 || input.StashBoxIndex >= len(boxes) { return false, err
return false, fmt.Errorf("invalid stash_box_index %d", input.StashBoxIndex)
} }
client := stashbox.NewClient(*boxes[input.StashBoxIndex], r.stashboxRepository()) client := r.newStashBoxClient(*b)
return client.SubmitStashBoxFingerprints(ctx, input.SceneIds)
return client.SubmitStashBoxFingerprints(ctx, input.SceneIds, boxes[input.StashBoxIndex].Endpoint)
} }
func (r *mutationResolver) StashBoxBatchPerformerTag(ctx context.Context, input manager.StashBoxBatchTagInput) (string, error) { func (r *mutationResolver) StashBoxBatchPerformerTag(ctx context.Context, input manager.StashBoxBatchTagInput) (string, error) {
jobID := manager.GetInstance().StashBoxBatchPerformerTag(ctx, input) b, err := resolveStashBoxBatchTagInput(input.Endpoint, input.StashBoxEndpoint)
if err != nil {
return "", err
}
jobID := manager.GetInstance().StashBoxBatchPerformerTag(ctx, b, input)
return strconv.Itoa(jobID), nil return strconv.Itoa(jobID), nil
} }
func (r *mutationResolver) StashBoxBatchStudioTag(ctx context.Context, input manager.StashBoxBatchTagInput) (string, error) { func (r *mutationResolver) StashBoxBatchStudioTag(ctx context.Context, input manager.StashBoxBatchTagInput) (string, error) {
jobID := manager.GetInstance().StashBoxBatchStudioTag(ctx, input) b, err := resolveStashBoxBatchTagInput(input.Endpoint, input.StashBoxEndpoint)
if err != nil {
return "", err
}
jobID := manager.GetInstance().StashBoxBatchStudioTag(ctx, b, input)
return strconv.Itoa(jobID), nil return strconv.Itoa(jobID), nil
} }
func (r *mutationResolver) SubmitStashBoxSceneDraft(ctx context.Context, input StashBoxDraftSubmissionInput) (*string, error) { func (r *mutationResolver) SubmitStashBoxSceneDraft(ctx context.Context, input StashBoxDraftSubmissionInput) (*string, error) {
boxes := config.GetInstance().GetStashBoxes() b, err := resolveStashBox(input.StashBoxIndex, input.StashBoxEndpoint)
if err != nil {
if input.StashBoxIndex < 0 || input.StashBoxIndex >= len(boxes) { return nil, err
return nil, fmt.Errorf("invalid stash_box_index %d", input.StashBoxIndex)
} }
client := stashbox.NewClient(*boxes[input.StashBoxIndex], r.stashboxRepository()) client := r.newStashBoxClient(*b)
id, err := strconv.Atoi(input.ID) id, err := strconv.Atoi(input.ID)
if err != nil { if err != nil {
@@ -68,7 +73,7 @@ func (r *mutationResolver) SubmitStashBoxSceneDraft(ctx context.Context, input S
return fmt.Errorf("loading scene URLs: %w", err) return fmt.Errorf("loading scene URLs: %w", err)
} }
res, err = client.SubmitSceneDraft(ctx, scene, boxes[input.StashBoxIndex].Endpoint, cover) res, err = client.SubmitSceneDraft(ctx, scene, cover)
return err return err
}) })
@@ -76,13 +81,12 @@ func (r *mutationResolver) SubmitStashBoxSceneDraft(ctx context.Context, input S
} }
func (r *mutationResolver) SubmitStashBoxPerformerDraft(ctx context.Context, input StashBoxDraftSubmissionInput) (*string, error) { func (r *mutationResolver) SubmitStashBoxPerformerDraft(ctx context.Context, input StashBoxDraftSubmissionInput) (*string, error) {
boxes := config.GetInstance().GetStashBoxes() b, err := resolveStashBox(input.StashBoxIndex, input.StashBoxEndpoint)
if err != nil {
if input.StashBoxIndex < 0 || input.StashBoxIndex >= len(boxes) { return nil, err
return nil, fmt.Errorf("invalid stash_box_index %d", input.StashBoxIndex)
} }
client := stashbox.NewClient(*boxes[input.StashBoxIndex], r.stashboxRepository()) client := r.newStashBoxClient(*b)
id, err := strconv.Atoi(input.ID) id, err := strconv.Atoi(input.ID)
if err != nil { if err != nil {
@@ -101,7 +105,7 @@ func (r *mutationResolver) SubmitStashBoxPerformerDraft(ctx context.Context, inp
return fmt.Errorf("performer with id %d not found", id) return fmt.Errorf("performer with id %d not found", id)
} }
res, err = client.SubmitPerformerDraft(ctx, performer, boxes[input.StashBoxIndex].Endpoint) res, err = client.SubmitPerformerDraft(ctx, performer)
return err return err
}) })

View File

@@ -9,7 +9,6 @@ import (
"strings" "strings"
"github.com/stashapp/stash/internal/manager" "github.com/stashapp/stash/internal/manager"
"github.com/stashapp/stash/internal/manager/config"
"github.com/stashapp/stash/pkg/logger" "github.com/stashapp/stash/pkg/logger"
"github.com/stashapp/stash/pkg/models" "github.com/stashapp/stash/pkg/models"
"github.com/stashapp/stash/pkg/scraper" "github.com/stashapp/stash/pkg/scraper"
@@ -190,18 +189,6 @@ func (r *queryResolver) ScrapeMovieURL(ctx context.Context, url string) (*models
return marshalScrapedMovie(content) return marshalScrapedMovie(content)
} }
func (r *queryResolver) getStashBoxClient(index int) (*stashbox.Client, error) {
boxes := config.GetInstance().GetStashBoxes()
if index < 0 || index >= len(boxes) {
return nil, fmt.Errorf("%w: invalid stash_box_index %d", ErrInput, index)
}
return stashbox.NewClient(*boxes[index], r.stashboxRepository()), nil
}
// FIXME - in the following resolvers, we're processing the deprecated field and not processing the new endpoint input
func (r *queryResolver) ScrapeSingleScene(ctx context.Context, source scraper.Source, input ScrapeSingleSceneInput) ([]*scraper.ScrapedScene, error) { func (r *queryResolver) ScrapeSingleScene(ctx context.Context, source scraper.Source, input ScrapeSingleSceneInput) ([]*scraper.ScrapedScene, error) {
var ret []*scraper.ScrapedScene var ret []*scraper.ScrapedScene
@@ -245,12 +232,14 @@ func (r *queryResolver) ScrapeSingleScene(ctx context.Context, source scraper.So
if err != nil { if err != nil {
return nil, err return nil, err
} }
case source.StashBoxIndex != nil: case source.StashBoxIndex != nil || source.StashBoxEndpoint != nil:
client, err := r.getStashBoxClient(*source.StashBoxIndex) b, err := resolveStashBox(source.StashBoxIndex, source.StashBoxEndpoint)
if err != nil { if err != nil {
return nil, err return nil, err
} }
client := r.newStashBoxClient(*b)
switch { switch {
case input.SceneID != nil: case input.SceneID != nil:
ret, err = client.FindStashBoxSceneByFingerprints(ctx, sceneID) ret, err = client.FindStashBoxSceneByFingerprints(ctx, sceneID)
@@ -275,12 +264,14 @@ func (r *queryResolver) ScrapeSingleScene(ctx context.Context, source scraper.So
func (r *queryResolver) ScrapeMultiScenes(ctx context.Context, source scraper.Source, input ScrapeMultiScenesInput) ([][]*scraper.ScrapedScene, error) { func (r *queryResolver) ScrapeMultiScenes(ctx context.Context, source scraper.Source, input ScrapeMultiScenesInput) ([][]*scraper.ScrapedScene, error) {
if source.ScraperID != nil { if source.ScraperID != nil {
return nil, ErrNotImplemented return nil, ErrNotImplemented
} else if source.StashBoxIndex != nil { } else if source.StashBoxIndex != nil || source.StashBoxEndpoint != nil {
client, err := r.getStashBoxClient(*source.StashBoxIndex) b, err := resolveStashBox(source.StashBoxIndex, source.StashBoxEndpoint)
if err != nil { if err != nil {
return nil, err return nil, err
} }
client := r.newStashBoxClient(*b)
sceneIDs, err := stringslice.StringSliceToIntSlice(input.SceneIds) sceneIDs, err := stringslice.StringSliceToIntSlice(input.SceneIds)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -293,12 +284,14 @@ func (r *queryResolver) ScrapeMultiScenes(ctx context.Context, source scraper.So
} }
func (r *queryResolver) ScrapeSingleStudio(ctx context.Context, source scraper.Source, input ScrapeSingleStudioInput) ([]*models.ScrapedStudio, error) { func (r *queryResolver) ScrapeSingleStudio(ctx context.Context, source scraper.Source, input ScrapeSingleStudioInput) ([]*models.ScrapedStudio, error) {
if source.StashBoxIndex != nil { if source.StashBoxIndex != nil || source.StashBoxEndpoint != nil {
client, err := r.getStashBoxClient(*source.StashBoxIndex) b, err := resolveStashBox(source.StashBoxIndex, source.StashBoxEndpoint)
if err != nil { if err != nil {
return nil, err return nil, err
} }
client := r.newStashBoxClient(*b)
var ret []*models.ScrapedStudio var ret []*models.ScrapedStudio
out, err := client.FindStashBoxStudio(ctx, *input.Query) out, err := client.FindStashBoxStudio(ctx, *input.Query)
@@ -346,13 +339,14 @@ func (r *queryResolver) ScrapeSinglePerformer(ctx context.Context, source scrape
default: default:
return nil, ErrNotImplemented return nil, ErrNotImplemented
} }
// FIXME - we're relying on a deprecated field and not processing the endpoint input case source.StashBoxIndex != nil || source.StashBoxEndpoint != nil:
case source.StashBoxIndex != nil: b, err := resolveStashBox(source.StashBoxIndex, source.StashBoxEndpoint)
client, err := r.getStashBoxClient(*source.StashBoxIndex)
if err != nil { if err != nil {
return nil, err return nil, err
} }
client := r.newStashBoxClient(*b)
var res []*stashbox.StashBoxPerformerQueryResult var res []*stashbox.StashBoxPerformerQueryResult
switch { switch {
case input.PerformerID != nil: case input.PerformerID != nil:
@@ -382,12 +376,14 @@ func (r *queryResolver) ScrapeSinglePerformer(ctx context.Context, source scrape
func (r *queryResolver) ScrapeMultiPerformers(ctx context.Context, source scraper.Source, input ScrapeMultiPerformersInput) ([][]*models.ScrapedPerformer, error) { func (r *queryResolver) ScrapeMultiPerformers(ctx context.Context, source scraper.Source, input ScrapeMultiPerformersInput) ([][]*models.ScrapedPerformer, error) {
if source.ScraperID != nil { if source.ScraperID != nil {
return nil, ErrNotImplemented return nil, ErrNotImplemented
} else if source.StashBoxIndex != nil { } else if source.StashBoxIndex != nil || source.StashBoxEndpoint != nil {
client, err := r.getStashBoxClient(*source.StashBoxIndex) b, err := resolveStashBox(source.StashBoxIndex, source.StashBoxEndpoint)
if err != nil { if err != nil {
return nil, err return nil, err
} }
client := r.newStashBoxClient(*b)
return client.FindStashBoxPerformersByPerformerNames(ctx, input.PerformerIds) return client.FindStashBoxPerformersByPerformerNames(ctx, input.PerformerIds)
} }
@@ -397,7 +393,7 @@ func (r *queryResolver) ScrapeMultiPerformers(ctx context.Context, source scrape
func (r *queryResolver) ScrapeSingleGallery(ctx context.Context, source scraper.Source, input ScrapeSingleGalleryInput) ([]*scraper.ScrapedGallery, error) { func (r *queryResolver) ScrapeSingleGallery(ctx context.Context, source scraper.Source, input ScrapeSingleGalleryInput) ([]*scraper.ScrapedGallery, error) {
var ret []*scraper.ScrapedGallery var ret []*scraper.ScrapedGallery
if source.StashBoxIndex != nil { if source.StashBoxIndex != nil || source.StashBoxEndpoint != nil {
return nil, ErrNotSupported return nil, ErrNotSupported
} }

45
internal/api/stash_box.go Normal file
View File

@@ -0,0 +1,45 @@
package api
import (
"fmt"
"strings"
"github.com/stashapp/stash/internal/manager/config"
"github.com/stashapp/stash/pkg/models"
"github.com/stashapp/stash/pkg/scraper/stashbox"
)
func (r *Resolver) newStashBoxClient(box models.StashBox) *stashbox.Client {
return stashbox.NewClient(box, r.stashboxRepository())
}
func resolveStashBoxFn(indexField, endpointField string) func(index *int, endpoint *string) (*models.StashBox, error) {
return func(index *int, endpoint *string) (*models.StashBox, error) {
boxes := config.GetInstance().GetStashBoxes()
// prefer endpoint over index
if endpoint != nil {
for _, box := range boxes {
if strings.EqualFold(*endpoint, box.Endpoint) {
return box, nil
}
}
return nil, fmt.Errorf("stash box not found")
}
if index != nil {
if *index < 0 || *index >= len(boxes) {
return nil, fmt.Errorf("invalid %s %d", indexField, index)
}
return boxes[*index], nil
}
return nil, fmt.Errorf("%s not provided", endpointField)
}
}
var (
resolveStashBox = resolveStashBoxFn("stash_box_index", "stash_box_endpoint")
resolveStashBoxBatchTagInput = resolveStashBoxFn("endpoint", "stash_box_endpoint")
)

View File

@@ -366,8 +366,9 @@ func (s *Manager) MigrateHash(ctx context.Context) int {
// If neither ids nor names are set, tag all items // If neither ids nor names are set, tag all items
type StashBoxBatchTagInput struct { type StashBoxBatchTagInput struct {
// Stash endpoint to use for the tagging // Stash endpoint to use for the tagging - deprecated - use StashBoxEndpoint
Endpoint int `json:"endpoint"` Endpoint *int `json:"endpoint"`
StashBoxEndpoint *string `json:"stash_box_endpoint"`
// Fields to exclude when executing the tagging // Fields to exclude when executing the tagging
ExcludeFields []string `json:"exclude_fields"` ExcludeFields []string `json:"exclude_fields"`
// Refresh items already tagged by StashBox if true. Only tag items with no StashBox tagging if false // Refresh items already tagged by StashBox if true. Only tag items with no StashBox tagging if false
@@ -388,16 +389,10 @@ type StashBoxBatchTagInput struct {
PerformerNames []string `json:"performer_names"` PerformerNames []string `json:"performer_names"`
} }
func (s *Manager) StashBoxBatchPerformerTag(ctx context.Context, input StashBoxBatchTagInput) int { func (s *Manager) StashBoxBatchPerformerTag(ctx context.Context, box *models.StashBox, input StashBoxBatchTagInput) int {
j := job.MakeJobExec(func(ctx context.Context, progress *job.Progress) error { j := job.MakeJobExec(func(ctx context.Context, progress *job.Progress) error {
logger.Infof("Initiating stash-box batch performer tag") logger.Infof("Initiating stash-box batch performer tag")
boxes := config.GetInstance().GetStashBoxes()
if input.Endpoint < 0 || input.Endpoint >= len(boxes) {
return fmt.Errorf("invalid stash_box_index %d", input.Endpoint)
}
box := boxes[input.Endpoint]
var tasks []StashBoxBatchTagTask var tasks []StashBoxBatchTagTask
// The gocritic linter wants to turn this ifElseChain into a switch. // The gocritic linter wants to turn this ifElseChain into a switch.
@@ -526,16 +521,10 @@ func (s *Manager) StashBoxBatchPerformerTag(ctx context.Context, input StashBoxB
return s.JobManager.Add(ctx, "Batch stash-box performer tag...", j) return s.JobManager.Add(ctx, "Batch stash-box performer tag...", j)
} }
func (s *Manager) StashBoxBatchStudioTag(ctx context.Context, input StashBoxBatchTagInput) int { func (s *Manager) StashBoxBatchStudioTag(ctx context.Context, box *models.StashBox, input StashBoxBatchTagInput) int {
j := job.MakeJobExec(func(ctx context.Context, progress *job.Progress) error { j := job.MakeJobExec(func(ctx context.Context, progress *job.Progress) error {
logger.Infof("Initiating stash-box batch studio tag") logger.Infof("Initiating stash-box batch studio tag")
boxes := config.GetInstance().GetStashBoxes()
if input.Endpoint < 0 || input.Endpoint >= len(boxes) {
return fmt.Errorf("invalid stash_box_index %d", input.Endpoint)
}
box := boxes[input.Endpoint]
var tasks []StashBoxBatchTagTask var tasks []StashBoxBatchTagTask
// The gocritic linter wants to turn this ifElseChain into a switch. // The gocritic linter wants to turn this ifElseChain into a switch.

View File

@@ -251,12 +251,14 @@ func (c Client) findStashBoxScenesByFingerprints(ctx context.Context, scenes [][
return ret, nil return ret, nil
} }
func (c Client) SubmitStashBoxFingerprints(ctx context.Context, sceneIDs []string, endpoint string) (bool, error) { func (c Client) SubmitStashBoxFingerprints(ctx context.Context, sceneIDs []string) (bool, error) {
ids, err := stringslice.StringSliceToIntSlice(sceneIDs) ids, err := stringslice.StringSliceToIntSlice(sceneIDs)
if err != nil { if err != nil {
return false, err return false, err
} }
endpoint := c.box.Endpoint
var fingerprints []graphql.FingerprintSubmission var fingerprints []graphql.FingerprintSubmission
r := c.repository r := c.repository
@@ -945,12 +947,13 @@ func appendFingerprintUnique(v []*graphql.FingerprintInput, toAdd *graphql.Finge
return append(v, toAdd) return append(v, toAdd)
} }
func (c Client) SubmitSceneDraft(ctx context.Context, scene *models.Scene, endpoint string, cover []byte) (*string, error) { func (c Client) SubmitSceneDraft(ctx context.Context, scene *models.Scene, cover []byte) (*string, error) {
draft := graphql.SceneDraftInput{} draft := graphql.SceneDraftInput{}
var image io.Reader var image io.Reader
r := c.repository r := c.repository
pqb := r.Performer pqb := r.Performer
sqb := r.Studio sqb := r.Studio
endpoint := c.box.Endpoint
if scene.Title != "" { if scene.Title != "" {
draft.Title = &scene.Title draft.Title = &scene.Title
@@ -1115,10 +1118,11 @@ func (c Client) SubmitSceneDraft(ctx context.Context, scene *models.Scene, endpo
// return id, nil // return id, nil
} }
func (c Client) SubmitPerformerDraft(ctx context.Context, performer *models.Performer, endpoint string) (*string, error) { func (c Client) SubmitPerformerDraft(ctx context.Context, performer *models.Performer) (*string, error) {
draft := graphql.PerformerDraftInput{} draft := graphql.PerformerDraftInput{}
var image io.Reader var image io.Reader
pqb := c.repository.Performer pqb := c.repository.Performer
endpoint := c.box.Endpoint
if err := performer.LoadAliases(ctx, pqb); err != nil { if err := performer.LoadAliases(ctx, pqb); err != nil {
return nil, err return nil, err

View File

@@ -52,17 +52,18 @@ export const SubmitStashBoxDraft: React.FC<IProps> = ({
}, [show, type, boxes, entity]); }, [show, type, boxes, entity]);
async function doSubmit() { async function doSubmit() {
if (!selectedBox) return;
const input = {
id: entity.id,
stash_box_endpoint: selectedBox.endpoint,
};
if (type === "scene") { if (type === "scene") {
const r = await mutateSubmitStashBoxSceneDraft({ const r = await mutateSubmitStashBoxSceneDraft(input);
id: entity.id,
stash_box_index: selectedBoxIndex,
});
return r.data?.submitStashBoxSceneDraft; return r.data?.submitStashBoxSceneDraft;
} else if (type === "performer") { } else if (type === "performer") {
const r = await mutateSubmitStashBoxPerformerDraft({ const r = await mutateSubmitStashBoxPerformerDraft(input);
id: entity.id,
stash_box_index: selectedBoxIndex,
});
return r.data?.submitStashBoxPerformerDraft; return r.data?.submitStashBoxPerformerDraft;
} }
} }

View File

@@ -160,7 +160,7 @@ const PerformerStashBoxModal: React.FC<IProps> = ({
const { data, loading } = GQL.useScrapeSinglePerformerQuery({ const { data, loading } = GQL.useScrapeSinglePerformerQuery({
variables: { variables: {
source: { source: {
stash_box_index: instance.index, stash_box_endpoint: instance.endpoint,
}, },
input: { input: {
query, query,

View File

@@ -419,7 +419,6 @@ export const SceneEditPanel: React.FC<IProps> = ({
key={s.endpoint} key={s.endpoint}
onClick={() => onClick={() =>
onScrapeQueryClicked({ onScrapeQueryClicked({
stash_box_index: index,
stash_box_endpoint: s.endpoint, stash_box_endpoint: s.endpoint,
}) })
} }
@@ -451,7 +450,7 @@ export const SceneEditPanel: React.FC<IProps> = ({
function onSceneSelected(s: GQL.ScrapedSceneDataFragment) { function onSceneSelected(s: GQL.ScrapedSceneDataFragment) {
if (!scraper) return; if (!scraper) return;
if (scraper?.stash_box_index !== undefined) { if (scraper?.stash_box_endpoint !== undefined) {
// must be stash-box - assume full scene // must be stash-box - assume full scene
setScrapedScene(s); setScrapedScene(s);
} else { } else {
@@ -491,7 +490,6 @@ export const SceneEditPanel: React.FC<IProps> = ({
key={s.endpoint} key={s.endpoint}
onClick={() => onClick={() =>
onScrapeClicked({ onScrapeClicked({
stash_box_index: index,
stash_box_endpoint: s.endpoint, stash_box_endpoint: s.endpoint,
}) })
} }

View File

@@ -5,7 +5,6 @@ export const SCRAPER_PREFIX = "scraper:";
export interface ITaggerSource { export interface ITaggerSource {
id: string; id: string;
stashboxEndpoint?: string;
sourceInput: ScraperSourceInput; sourceInput: ScraperSourceInput;
displayName: string; displayName: string;
supportSceneQuery?: boolean; supportSceneQuery?: boolean;

View File

@@ -146,10 +146,9 @@ export const TaggerContext: React.FC = ({ children }) => {
const scrapers = Scrapers.data.listScrapers; const scrapers = Scrapers.data.listScrapers;
const stashboxSources: ITaggerSource[] = stashBoxes.map((s, i) => ({ const stashboxSources: ITaggerSource[] = stashBoxes.map((s, i) => ({
id: `${STASH_BOX_PREFIX}${i}`, id: `${STASH_BOX_PREFIX}${s.endpoint}`,
stashboxEndpoint: s.endpoint,
sourceInput: { sourceInput: {
stash_box_index: i, stash_box_endpoint: s.endpoint,
}, },
displayName: `stash-box: ${s.name || `#${i + 1}`}`, displayName: `stash-box: ${s.name || `#${i + 1}`}`,
supportSceneFragment: true, supportSceneFragment: true,
@@ -192,14 +191,14 @@ export const TaggerContext: React.FC = ({ children }) => {
}, [currentSource]); }, [currentSource]);
function getPendingFingerprints() { function getPendingFingerprints() {
const endpoint = currentSource?.stashboxEndpoint; const endpoint = currentSource?.sourceInput.stash_box_endpoint;
if (!config || !endpoint) return []; if (!config || !endpoint) return [];
return config.fingerprintQueue[endpoint] ?? []; return config.fingerprintQueue[endpoint] ?? [];
} }
function clearSubmissionQueue() { function clearSubmissionQueue() {
const endpoint = currentSource?.stashboxEndpoint; const endpoint = currentSource?.sourceInput.stash_box_endpoint;
if (!config || !endpoint) return; if (!config || !endpoint) return;
setConfig({ setConfig({
@@ -215,18 +214,16 @@ export const TaggerContext: React.FC = ({ children }) => {
GQL.useSubmitStashBoxFingerprintsMutation(); GQL.useSubmitStashBoxFingerprintsMutation();
async function submitFingerprints() { async function submitFingerprints() {
const endpoint = currentSource?.stashboxEndpoint; const endpoint = currentSource?.sourceInput.stash_box_endpoint;
const stashBoxIndex =
currentSource?.sourceInput.stash_box_index ?? undefined;
if (!config || !endpoint || stashBoxIndex === undefined) return; if (!config || !endpoint) return;
try { try {
setLoading(true); setLoading(true);
await submitFingerprintsMutation({ await submitFingerprintsMutation({
variables: { variables: {
input: { input: {
stash_box_index: stashBoxIndex, stash_box_endpoint: endpoint,
scene_ids: config.fingerprintQueue[endpoint], scene_ids: config.fingerprintQueue[endpoint],
}, },
}, },
@@ -241,7 +238,7 @@ export const TaggerContext: React.FC = ({ children }) => {
} }
function queueFingerprintSubmission(sceneId: string) { function queueFingerprintSubmission(sceneId: string) {
const endpoint = currentSource?.stashboxEndpoint; const endpoint = currentSource?.sourceInput.stash_box_endpoint;
if (!config || !endpoint) return; if (!config || !endpoint) return;
setConfig({ setConfig({
@@ -276,7 +273,8 @@ export const TaggerContext: React.FC = ({ children }) => {
); );
let newResult: ISceneQueryResult; let newResult: ISceneQueryResult;
// scenes are already resolved if they come from stash-box // scenes are already resolved if they come from stash-box
const resolved = currentSource.sourceInput.stash_box_index !== undefined; const resolved =
currentSource.sourceInput.stash_box_endpoint !== undefined;
if (results.error) { if (results.error) {
newResult = { error: results.error.message }; newResult = { error: results.error.message };
@@ -365,13 +363,16 @@ export const TaggerContext: React.FC = ({ children }) => {
setLoading(true); setLoading(true);
setMultiError(undefined); setMultiError(undefined);
const stashBoxIndex = const stashBoxEndpoint =
currentSource.sourceInput.stash_box_index ?? undefined; currentSource.sourceInput.stash_box_endpoint ?? undefined;
// if current source is stash-box, we can use the multi-scene // if current source is stash-box, we can use the multi-scene
// interface // interface
if (stashBoxIndex !== undefined) { if (stashBoxEndpoint !== undefined) {
const results = await stashBoxSceneBatchQuery(sceneIDs, stashBoxIndex); const results = await stashBoxSceneBatchQuery(
sceneIDs,
stashBoxEndpoint
);
if (results.error) { if (results.error) {
setMultiError(results.error.message); setMultiError(results.error.message);
@@ -604,7 +605,11 @@ export const TaggerContext: React.FC = ({ children }) => {
performer: GQL.ScrapedPerformer, performer: GQL.ScrapedPerformer,
performerID: string performerID: string
) { ) {
if (!performer.remote_site_id || !currentSource?.stashboxEndpoint) return; if (
!performer.remote_site_id ||
!currentSource?.sourceInput.stash_box_endpoint
)
return;
try { try {
const queryResult = await queryFindPerformer(performerID); const queryResult = await queryFindPerformer(performerID);
@@ -620,7 +625,7 @@ export const TaggerContext: React.FC = ({ children }) => {
stashIDs.push({ stashIDs.push({
stash_id: performer.remote_site_id, stash_id: performer.remote_site_id,
endpoint: currentSource?.stashboxEndpoint, endpoint: currentSource?.sourceInput.stash_box_endpoint,
}); });
await updatePerformer({ await updatePerformer({
@@ -722,7 +727,7 @@ export const TaggerContext: React.FC = ({ children }) => {
const studioID = result.data?.studioUpdate?.id; const studioID = result.data?.studioUpdate?.id;
const stashID = input.stash_ids?.find((e) => { const stashID = input.stash_ids?.find((e) => {
return e.endpoint === currentSource?.stashboxEndpoint; return e.endpoint === currentSource?.sourceInput.stash_box_endpoint;
})?.stash_id; })?.stash_id;
if (stashID) { if (stashID) {
@@ -757,7 +762,11 @@ export const TaggerContext: React.FC = ({ children }) => {
} }
async function linkStudio(studio: GQL.ScrapedStudio, studioID: string) { async function linkStudio(studio: GQL.ScrapedStudio, studioID: string) {
if (!studio.remote_site_id || !currentSource?.stashboxEndpoint) return; if (
!studio.remote_site_id ||
!currentSource?.sourceInput.stash_box_endpoint
)
return;
try { try {
const queryResult = await queryFindStudio(studioID); const queryResult = await queryFindStudio(studioID);
@@ -773,7 +782,7 @@ export const TaggerContext: React.FC = ({ children }) => {
stashIDs.push({ stashIDs.push({
stash_id: studio.remote_site_id, stash_id: studio.remote_site_id,
endpoint: currentSource?.stashboxEndpoint, endpoint: currentSource?.sourceInput.stash_box_endpoint,
}); });
await updateStudio({ await updateStudio({

View File

@@ -238,7 +238,6 @@ interface IPerformerTaggerListProps {
selectedEndpoint: { endpoint: string; index: number }; selectedEndpoint: { endpoint: string; index: number };
isIdle: boolean; isIdle: boolean;
config: ITaggerConfig; config: ITaggerConfig;
stashBoxes?: GQL.StashBox[];
onBatchAdd: (performerInput: string) => void; onBatchAdd: (performerInput: string) => void;
onBatchUpdate: (ids: string[] | undefined, refresh: boolean) => void; onBatchUpdate: (ids: string[] | undefined, refresh: boolean) => void;
} }
@@ -248,7 +247,6 @@ const PerformerTaggerList: React.FC<IPerformerTaggerListProps> = ({
selectedEndpoint, selectedEndpoint,
isIdle, isIdle,
config, config,
stashBoxes,
onBatchAdd, onBatchAdd,
onBatchUpdate, onBatchUpdate,
}) => { }) => {
@@ -277,7 +275,7 @@ const PerformerTaggerList: React.FC<IPerformerTaggerListProps> = ({
>(); >();
const doBoxSearch = (performerID: string, searchVal: string) => { const doBoxSearch = (performerID: string, searchVal: string) => {
stashBoxPerformerQuery(searchVal, selectedEndpoint.index) stashBoxPerformerQuery(searchVal, selectedEndpoint.endpoint)
.then((queryData) => { .then((queryData) => {
const s = queryData.data?.scrapeSinglePerformer ?? []; const s = queryData.data?.scrapeSinglePerformer ?? [];
setSearchResults({ setSearchResults({
@@ -309,14 +307,14 @@ const PerformerTaggerList: React.FC<IPerformerTaggerListProps> = ({
const doBoxUpdate = ( const doBoxUpdate = (
performerID: string, performerID: string,
stashID: string, stashID: string,
endpointIndex: number endpoint: string
) => { ) => {
setLoadingUpdate(stashID); setLoadingUpdate(stashID);
setError({ setError({
...error, ...error,
[performerID]: undefined, [performerID]: undefined,
}); });
stashBoxPerformerQuery(stashID, endpointIndex) stashBoxPerformerQuery(stashID, endpoint)
.then((queryData) => { .then((queryData) => {
const data = queryData.data?.scrapeSinglePerformer ?? []; const data = queryData.data?.scrapeSinglePerformer ?? [];
if (data.length > 0) { if (data.length > 0) {
@@ -477,29 +475,27 @@ const PerformerTaggerList: React.FC<IPerformerTaggerListProps> = ({
<div className="small">{stashID.stash_id}</div> <div className="small">{stashID.stash_id}</div>
); );
const endpointIndex =
stashBoxes?.findIndex((box) => box.endpoint === stashID.endpoint) ??
-1;
subContent = ( subContent = (
<div key={performer.id}> <div key={performer.id}>
<InputGroup className="PerformerTagger-box-link"> <InputGroup className="PerformerTagger-box-link">
<InputGroup.Text>{link}</InputGroup.Text> <InputGroup.Text>{link}</InputGroup.Text>
<InputGroup.Append> <InputGroup.Append>
{endpointIndex !== -1 && ( <Button
<Button onClick={() =>
onClick={() => doBoxUpdate(
doBoxUpdate(performer.id, stashID.stash_id, endpointIndex) performer.id,
} stashID.stash_id,
disabled={!!loadingUpdate} stashID.endpoint
> )
{loadingUpdate === stashID.stash_id ? ( }
<LoadingIndicator inline small message="" /> disabled={!!loadingUpdate}
) : ( >
<FormattedMessage id="actions.refresh" /> {loadingUpdate === stashID.stash_id ? (
)} <LoadingIndicator inline small message="" />
</Button> ) : (
)} <FormattedMessage id="actions.refresh" />
)}
</Button>
</InputGroup.Append> </InputGroup.Append>
</InputGroup> </InputGroup>
{error[performer.id] && ( {error[performer.id] && (
@@ -787,7 +783,6 @@ export const PerformerTagger: React.FC<ITaggerProps> = ({ performers }) => {
}} }}
isIdle={batchJobID === undefined} isIdle={batchJobID === undefined}
config={config} config={config}
stashBoxes={stashConfig?.general.stashBoxes}
onBatchAdd={batchAdd} onBatchAdd={batchAdd}
onBatchUpdate={batchUpdate} onBatchUpdate={batchUpdate}
/> />

View File

@@ -327,8 +327,8 @@ const StashSearchResult: React.FC<IStashSearchResultProps> = ({
} }
}, [isActive, loading, stashScene, index, resolveScene, scene]); }, [isActive, loading, stashScene, index, resolveScene, scene]);
const stashBoxBaseURL = currentSource?.stashboxEndpoint const stashBoxBaseURL = currentSource?.sourceInput.stash_box_endpoint
? getStashboxBase(currentSource.stashboxEndpoint) ? getStashboxBase(currentSource.sourceInput.stash_box_endpoint)
: undefined; : undefined;
const stashBoxURL = useMemo(() => { const stashBoxURL = useMemo(() => {
if (stashBoxBaseURL) { if (stashBoxBaseURL) {
@@ -404,7 +404,7 @@ const StashSearchResult: React.FC<IStashSearchResultProps> = ({
const includeStashID = !excludedFieldList.includes("stash_ids"); const includeStashID = !excludedFieldList.includes("stash_ids");
if ( if (
includeStashID && includeStashID &&
currentSource?.stashboxEndpoint && currentSource?.sourceInput.stash_box_endpoint &&
scene.remote_site_id scene.remote_site_id
) { ) {
sceneCreateInput.stash_ids = [ sceneCreateInput.stash_ids = [
@@ -415,9 +415,11 @@ const StashSearchResult: React.FC<IStashSearchResultProps> = ({
stash_id: s.stash_id, stash_id: s.stash_id,
}; };
}) })
.filter((s) => s.endpoint !== currentSource.stashboxEndpoint) ?? []), .filter(
(s) => s.endpoint !== currentSource.sourceInput.stash_box_endpoint
) ?? []),
{ {
endpoint: currentSource.stashboxEndpoint, endpoint: currentSource.sourceInput.stash_box_endpoint,
stash_id: scene.remote_site_id, stash_id: scene.remote_site_id,
}, },
]; ];
@@ -662,7 +664,9 @@ const StashSearchResult: React.FC<IStashSearchResultProps> = ({
selectedID={studioID} selectedID={studioID}
setSelectedID={(id) => setStudioID(id)} setSelectedID={(id) => setStudioID(id)}
onCreate={() => showStudioModal(scene.studio!)} onCreate={() => showStudioModal(scene.studio!)}
endpoint={currentSource?.stashboxEndpoint} endpoint={
currentSource?.sourceInput.stash_box_endpoint ?? undefined
}
onLink={async () => { onLink={async () => {
await linkStudio(scene.studio!, studioID!); await linkStudio(scene.studio!, studioID!);
}} }}
@@ -691,7 +695,9 @@ const StashSearchResult: React.FC<IStashSearchResultProps> = ({
onLink={async () => { onLink={async () => {
await linkPerformer(performer, performerIDs[performerIndex]!); await linkPerformer(performer, performerIDs[performerIndex]!);
}} }}
endpoint={currentSource?.stashboxEndpoint} endpoint={
currentSource?.sourceInput.stash_box_endpoint ?? undefined
}
key={`${performer.name ?? performer.remote_site_id ?? ""}`} key={`${performer.name ?? performer.remote_site_id ?? ""}`}
/> />
))} ))}

View File

@@ -106,7 +106,7 @@ export const SceneTaggerModals: React.FC = ({ children }) => {
setStudioCallback(() => callback); setStudioCallback(() => callback);
} }
const endpoint = currentSource?.stashboxEndpoint; const endpoint = currentSource?.sourceInput.stash_box_endpoint ?? undefined;
return ( return (
<SceneTaggerModalsState.Provider <SceneTaggerModalsState.Provider

View File

@@ -268,7 +268,6 @@ interface IStudioTaggerListProps {
selectedEndpoint: { endpoint: string; index: number }; selectedEndpoint: { endpoint: string; index: number };
isIdle: boolean; isIdle: boolean;
config: ITaggerConfig; config: ITaggerConfig;
stashBoxes?: GQL.StashBox[];
onBatchAdd: (studioInput: string, createParent: boolean) => void; onBatchAdd: (studioInput: string, createParent: boolean) => void;
onBatchUpdate: ( onBatchUpdate: (
ids: string[] | undefined, ids: string[] | undefined,
@@ -282,7 +281,6 @@ const StudioTaggerList: React.FC<IStudioTaggerListProps> = ({
selectedEndpoint, selectedEndpoint,
isIdle, isIdle,
config, config,
stashBoxes,
onBatchAdd, onBatchAdd,
onBatchUpdate, onBatchUpdate,
}) => { }) => {
@@ -315,7 +313,7 @@ const StudioTaggerList: React.FC<IStudioTaggerListProps> = ({
>(); >();
const doBoxSearch = (studioID: string, searchVal: string) => { const doBoxSearch = (studioID: string, searchVal: string) => {
stashBoxStudioQuery(searchVal, selectedEndpoint.index) stashBoxStudioQuery(searchVal, selectedEndpoint.endpoint)
.then((queryData) => { .then((queryData) => {
const s = queryData.data?.scrapeSingleStudio ?? []; const s = queryData.data?.scrapeSingleStudio ?? [];
setSearchResults({ setSearchResults({
@@ -344,17 +342,13 @@ const StudioTaggerList: React.FC<IStudioTaggerListProps> = ({
setLoading(true); setLoading(true);
}; };
const doBoxUpdate = ( const doBoxUpdate = (studioID: string, stashID: string, endpoint: string) => {
studioID: string,
stashID: string,
endpointIndex: number
) => {
setLoadingUpdate(stashID); setLoadingUpdate(stashID);
setError({ setError({
...error, ...error,
[studioID]: undefined, [studioID]: undefined,
}); });
stashBoxStudioQuery(stashID, endpointIndex) stashBoxStudioQuery(stashID, endpoint)
.then((queryData) => { .then((queryData) => {
const data = queryData.data?.scrapeSingleStudio ?? []; const data = queryData.data?.scrapeSingleStudio ?? [];
if (data.length > 0) { if (data.length > 0) {
@@ -535,29 +529,23 @@ const StudioTaggerList: React.FC<IStudioTaggerListProps> = ({
<div className="small">{stashID.stash_id}</div> <div className="small">{stashID.stash_id}</div>
); );
const endpointIndex =
stashBoxes?.findIndex((box) => box.endpoint === stashID.endpoint) ??
-1;
subContent = ( subContent = (
<div key={studio.id}> <div key={studio.id}>
<InputGroup className="StudioTagger-box-link"> <InputGroup className="StudioTagger-box-link">
<InputGroup.Text>{link}</InputGroup.Text> <InputGroup.Text>{link}</InputGroup.Text>
<InputGroup.Append> <InputGroup.Append>
{endpointIndex !== -1 && ( <Button
<Button onClick={() =>
onClick={() => doBoxUpdate(studio.id, stashID.stash_id, stashID.endpoint)
doBoxUpdate(studio.id, stashID.stash_id, endpointIndex) }
} disabled={!!loadingUpdate}
disabled={!!loadingUpdate} >
> {loadingUpdate === stashID.stash_id ? (
{loadingUpdate === stashID.stash_id ? ( <LoadingIndicator inline small message="" />
<LoadingIndicator inline small message="" /> ) : (
) : ( <FormattedMessage id="actions.refresh" />
<FormattedMessage id="actions.refresh" /> )}
)} </Button>
</Button>
)}
</InputGroup.Append> </InputGroup.Append>
</InputGroup> </InputGroup>
{error[studio.id] && ( {error[studio.id] && (
@@ -849,7 +837,6 @@ export const StudioTagger: React.FC<ITaggerProps> = ({ studios }) => {
}} }}
isIdle={batchJobID === undefined} isIdle={batchJobID === undefined}
config={config} config={config}
stashBoxes={stashConfig?.general.stashBoxes}
onBatchAdd={batchAdd} onBatchAdd={batchAdd}
onBatchUpdate={batchUpdate} onBatchUpdate={batchUpdate}
/> />

View File

@@ -2054,19 +2054,21 @@ export const queryScrapeSceneQueryFragment = (
export const stashBoxSceneBatchQuery = ( export const stashBoxSceneBatchQuery = (
sceneIds: string[], sceneIds: string[],
stashBoxIndex: number stashBoxEndpoint: string
) => ) =>
client.query<GQL.ScrapeMultiScenesQuery>({ client.query<GQL.ScrapeMultiScenesQuery, GQL.ScrapeMultiScenesQueryVariables>(
query: GQL.ScrapeMultiScenesDocument, {
variables: { query: GQL.ScrapeMultiScenesDocument,
source: { variables: {
stash_box_index: stashBoxIndex, source: {
stash_box_endpoint: stashBoxEndpoint,
},
input: {
scene_ids: sceneIds,
},
}, },
input: { }
scene_ids: sceneIds, );
},
},
});
export const useListPerformerScrapers = () => export const useListPerformerScrapers = () =>
GQL.useListPerformerScrapersQuery(); GQL.useListPerformerScrapersQuery();
@@ -2110,13 +2112,16 @@ export const queryScrapePerformerURL = (url: string) =>
export const stashBoxPerformerQuery = ( export const stashBoxPerformerQuery = (
searchVal: string, searchVal: string,
stashBoxIndex: number stashBoxEndpoint: string
) => ) =>
client.query<GQL.ScrapeSinglePerformerQuery>({ client.query<
GQL.ScrapeSinglePerformerQuery,
GQL.ScrapeSinglePerformerQueryVariables
>({
query: GQL.ScrapeSinglePerformerDocument, query: GQL.ScrapeSinglePerformerDocument,
variables: { variables: {
source: { source: {
stash_box_index: stashBoxIndex, stash_box_endpoint: stashBoxEndpoint,
}, },
input: { input: {
query: searchVal, query: searchVal,
@@ -2127,13 +2132,16 @@ export const stashBoxPerformerQuery = (
export const stashBoxStudioQuery = ( export const stashBoxStudioQuery = (
query: string | null, query: string | null,
stashBoxIndex: number stashBoxEndpoint: string
) => ) =>
client.query<GQL.ScrapeSingleStudioQuery>({ client.query<
GQL.ScrapeSingleStudioQuery,
GQL.ScrapeSingleStudioQueryVariables
>({
query: GQL.ScrapeSingleStudioDocument, query: GQL.ScrapeSingleStudioDocument,
variables: { variables: {
source: { source: {
stash_box_index: stashBoxIndex, stash_box_endpoint: stashBoxEndpoint,
}, },
input: { input: {
query: query, query: query,