mirror of
https://github.com/stashapp/stash.git
synced 2025-12-17 04:14:39 +03:00
Refactor stashbox package (#5699)
* Move stashbox package under pkg * Remove StashBox from method names * Add fingerprint conversion methods to Fingerprint Refactor Fingerprints methods * Make FindSceneByFingerprints accept fingerprints not scene ids * Refactor SubmitSceneDraft to not require readers * Have SubmitFingerprints accept scenes Remove SceneReader dependency * Move ScrapedScene to models package * Move ScrapedImage into models package * Move ScrapedGallery into models package * Move Scene relationship matching out of stashbox package This is now expected to be done in the client code * Remove TagFinder dependency from stashbox.Client * Make stashbox scene find full hierarchy of studios * Move studio resolution into separate method * Move studio matching out of stashbox package This is now client code responsibility * Move performer matching out of FindPerformerByID and FindPerformerByName * Refactor performer querying logic and remove unused stashbox models Renames FindStashBoxPerformersByPerformerNames to QueryPerformers and accepts names instead of performer ids * Refactor SubmitPerformerDraft to not load relationships This will be the responsibility of the calling code * Remove repository references
This commit is contained in:
132
pkg/stashbox/draft.go
Normal file
132
pkg/stashbox/draft.go
Normal file
@@ -0,0 +1,132 @@
|
||||
package stashbox
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
|
||||
"github.com/Yamashou/gqlgenc/clientv2"
|
||||
"github.com/Yamashou/gqlgenc/graphqljson"
|
||||
)
|
||||
|
||||
func (c *Client) submitDraft(ctx context.Context, query string, input interface{}, image io.Reader, ret interface{}) error {
|
||||
vars := map[string]interface{}{
|
||||
"input": input,
|
||||
}
|
||||
|
||||
r := &clientv2.Request{
|
||||
Query: query,
|
||||
Variables: vars,
|
||||
OperationName: "",
|
||||
}
|
||||
|
||||
requestBody, err := json.Marshal(r)
|
||||
if err != nil {
|
||||
return fmt.Errorf("encode: %w", err)
|
||||
}
|
||||
|
||||
body := &bytes.Buffer{}
|
||||
writer := multipart.NewWriter(body)
|
||||
if err := writer.WriteField("operations", string(requestBody)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if image != nil {
|
||||
if err := writer.WriteField("map", "{ \"0\": [\"variables.input.image\"] }"); err != nil {
|
||||
return err
|
||||
}
|
||||
part, _ := writer.CreateFormFile("0", "draft")
|
||||
if _, err := io.Copy(part, image); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if err := writer.WriteField("map", "{}"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
writer.Close()
|
||||
|
||||
req, _ := http.NewRequestWithContext(ctx, "POST", c.box.Endpoint, body)
|
||||
req.Header.Add("Content-Type", writer.FormDataContentType())
|
||||
req.Header.Set("ApiKey", c.box.APIKey)
|
||||
|
||||
httpClient := c.client.Client.Client
|
||||
resp, err := httpClient.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
responseBytes, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
type response struct {
|
||||
Data json.RawMessage `json:"data"`
|
||||
Errors json.RawMessage `json:"errors"`
|
||||
}
|
||||
|
||||
var respGQL response
|
||||
|
||||
if err := json.Unmarshal(responseBytes, &respGQL); err != nil {
|
||||
return fmt.Errorf("failed to decode data %s: %w", string(responseBytes), err)
|
||||
}
|
||||
|
||||
if len(respGQL.Errors) > 0 {
|
||||
// try to parse standard graphql error
|
||||
errors := &clientv2.GqlErrorList{}
|
||||
if e := json.Unmarshal(responseBytes, errors); e != nil {
|
||||
return fmt.Errorf("failed to parse graphql errors. Response content %s - %w ", string(responseBytes), e)
|
||||
}
|
||||
|
||||
return errors
|
||||
}
|
||||
|
||||
if err := graphqljson.UnmarshalData(respGQL.Data, ret); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// we can't currently use this due to https://github.com/Yamashou/gqlgenc/issues/109
|
||||
// func uploadImage(image io.Reader) client.HTTPRequestOption {
|
||||
// return func(req *http.Request) {
|
||||
// if image == nil {
|
||||
// // return without changing anything
|
||||
// return
|
||||
// }
|
||||
|
||||
// // we can't handle errors in here, so if one happens, just return
|
||||
// // without changing anything.
|
||||
|
||||
// // repackage the request to include the image
|
||||
// bodyBytes, err := ioutil.ReadAll(req.Body)
|
||||
// if err != nil {
|
||||
// return
|
||||
// }
|
||||
|
||||
// newBody := &bytes.Buffer{}
|
||||
// writer := multipart.NewWriter(newBody)
|
||||
// _ = writer.WriteField("operations", string(bodyBytes))
|
||||
|
||||
// if err := writer.WriteField("map", "{ \"0\": [\"variables.input.image\"] }"); err != nil {
|
||||
// return
|
||||
// }
|
||||
// part, _ := writer.CreateFormFile("0", "draft")
|
||||
// if _, err := io.Copy(part, image); err != nil {
|
||||
// return
|
||||
// }
|
||||
|
||||
// writer.Close()
|
||||
|
||||
// // now set the request body to this new body
|
||||
// req.Body = io.NopCloser(newBody)
|
||||
// req.ContentLength = int64(newBody.Len())
|
||||
// req.Header.Set("Content-Type", writer.FormDataContentType())
|
||||
// }
|
||||
// }
|
||||
Reference in New Issue
Block a user