Skip to content

Commit

Permalink
Support setting api key for stash server
Browse files Browse the repository at this point in the history
  • Loading branch information
WithoutPants committed Nov 12, 2024
1 parent f75989f commit 62ae6fa
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 15 deletions.
3 changes: 2 additions & 1 deletion pkg/scraper/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,8 @@ func (c config) validate() error {
}

type stashServer struct {
URL string `yaml:"url"`
URL string `yaml:"url"`
ApiKey string `yaml:"apiKey"`
}

type scraperTypeConfig struct {
Expand Down
33 changes: 26 additions & 7 deletions pkg/scraper/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,13 +122,19 @@ func setGroupBackImage(ctx context.Context, client *http.Client, m *models.Scrap
return nil
}

func getImage(ctx context.Context, url string, client *http.Client, globalConfig GlobalConfig) (*string, error) {
type imageGetter struct {
client *http.Client
globalConfig GlobalConfig
requestModifier func(req *http.Request)
}

func (i *imageGetter) getImage(ctx context.Context, url string) (*string, error) {
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
if err != nil {
return nil, err
}

userAgent := globalConfig.GetScraperUserAgent()
userAgent := i.globalConfig.GetScraperUserAgent()
if userAgent != "" {
req.Header.Set("User-Agent", userAgent)
}
Expand All @@ -140,7 +146,11 @@ func getImage(ctx context.Context, url string, client *http.Client, globalConfig
req.Header.Set("Referer", req.URL.Scheme+"://"+req.Host+"/")
}

resp, err := client.Do(req)
if i.requestModifier != nil {
i.requestModifier(req)
}

resp, err := i.client.Do(req)

if err != nil {
return nil, err
Expand All @@ -167,10 +177,19 @@ func getImage(ctx context.Context, url string, client *http.Client, globalConfig
return &img, nil
}

func getStashPerformerImage(ctx context.Context, stashURL string, performerID string, client *http.Client, globalConfig GlobalConfig) (*string, error) {
return getImage(ctx, stashURL+"/performer/"+performerID+"/image", client, globalConfig)
func getImage(ctx context.Context, url string, client *http.Client, globalConfig GlobalConfig) (*string, error) {
g := imageGetter{
client: client,
globalConfig: globalConfig,
}

return g.getImage(ctx, url)
}

func getStashPerformerImage(ctx context.Context, stashURL string, performerID string, imageGetter imageGetter) (*string, error) {
return imageGetter.getImage(ctx, stashURL+"/performer/"+performerID+"/image")
}

func getStashSceneImage(ctx context.Context, stashURL string, sceneID string, client *http.Client, globalConfig GlobalConfig) (*string, error) {
return getImage(ctx, stashURL+"/scene/"+sceneID+"/screenshot", client, globalConfig)
func getStashSceneImage(ctx context.Context, stashURL string, sceneID string, imageGetter imageGetter) (*string, error) {
return imageGetter.getImage(ctx, stashURL+"/scene/"+sceneID+"/screenshot")
}
40 changes: 34 additions & 6 deletions pkg/scraper/stash.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,21 @@ func newStashScraper(scraper scraperTypeConfig, client *http.Client, config conf
}
}

func setApiKeyHeader(apiKey string) func(req *http.Request) {
return func(req *http.Request) {
req.Header.Set("ApiKey", apiKey)
}
}

func (s *stashScraper) getStashClient() *graphql.Client {
url := s.config.StashServer.URL
return graphql.NewClient(url+"/graphql", nil)
url := s.config.StashServer.URL + "/graphql"
ret := graphql.NewClient(url, s.client)

if s.config.StashServer.ApiKey != "" {
ret = ret.WithRequestModifier(setApiKeyHeader(s.config.StashServer.ApiKey))
}

return ret
}

type stashFindPerformerNamePerformer struct {
Expand Down Expand Up @@ -81,6 +93,19 @@ type scrapedPerformerStash struct {
Weight *int `graphql:"weight" json:"weight"`
}

func (s *stashScraper) imageGetter() imageGetter {
ret := imageGetter{
client: s.client,
globalConfig: s.globalConfig,
}

if s.config.StashServer.ApiKey != "" {
ret.requestModifier = setApiKeyHeader(s.config.StashServer.ApiKey)
}

return ret
}

func (s *stashScraper) scrapeByFragment(ctx context.Context, input Input) (ScrapedContent, error) {
if input.Gallery != nil || input.Scene != nil {
return nil, fmt.Errorf("%w: using stash scraper as a fragment scraper", ErrNotSupported)
Expand Down Expand Up @@ -132,7 +157,8 @@ func (s *stashScraper) scrapeByFragment(ctx context.Context, input Input) (Scrap
}

// get the performer image directly
ret.Image, err = getStashPerformerImage(ctx, s.config.StashServer.URL, performerID, s.client, s.globalConfig)
ig := s.imageGetter()
img, err := getStashPerformerImage(ctx, s.config.StashServer.URL, performerID, ig)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -165,8 +191,9 @@ func (s *stashScraper) scrapedStashSceneToScrapedScene(ctx context.Context, scen
ret.File = &f
}

// get the performer image directly
ret.Image, err = getStashSceneImage(ctx, s.config.StashServer.URL, scene.ID, s.client, s.globalConfig)
// get the scene image directly
ig := s.imageGetter()
ret.Image, err = getStashSceneImage(ctx, s.config.StashServer.URL, scene.ID, ig)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -308,7 +335,8 @@ func (s *stashScraper) scrapeSceneByScene(ctx context.Context, scene *models.Sce
}

// get the performer image directly
ret.Image, err = getStashSceneImage(ctx, s.config.StashServer.URL, q.FindScene.ID, s.client, s.globalConfig)
ig := s.imageGetter()
ret.Image, err = getStashSceneImage(ctx, s.config.StashServer.URL, q.FindScene.ID, ig)
if err != nil {
return nil, err
}
Expand Down
3 changes: 2 additions & 1 deletion ui/v2.5/src/docs/en/Manual/ScraperDevelopment.md
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ sceneByURL:

A different stash server can be configured as a scraping source. This action applies only to `performerByName`, `performerByFragment`, and `sceneByFragment` types. This action requires that the top-level `stashServer` field is configured.

`stashServer` contains a single `url` field for the remote stash server. The username and password can be embedded in this string using `username:password@host`.
`stashServer` contains a single `url` field for the remote stash server. The username and password can be embedded in this string using `username:password@host`. Alternatively, the `apiKey` field can be used to authenticate with the remote stash server.

An example stash scrape configuration is below:

Expand All @@ -260,6 +260,7 @@ performerByFragment:
sceneByFragment:
action: stash
stashServer:
apiKey: <api key>
url: http://stashserver.com:9999
```

Expand Down

0 comments on commit 62ae6fa

Please sign in to comment.