Files
go-midjourney/client.go
2022-09-15 23:06:08 +01:00

138 lines
2.5 KiB
Go

package midjourney
import (
"errors"
"fmt"
"net/http"
"net/url"
"strings"
"github.com/rs/zerolog"
)
var (
Err = errors.New("midjourney")
ErrNoAuthToken = fmt.Errorf("%w: no auth token", Err)
ErrInvalidAPIURL = fmt.Errorf("%w: invalid API URL", Err)
ErrInvalidHTTPClient = fmt.Errorf("%w: invalid HTTP client", Err)
ErrResponseStatus = fmt.Errorf("%w: response status", Err)
DefaultAPIURL = url.URL{
Scheme: "https",
Host: "www.midjourney.com",
Path: "/api/",
}
DefaultUserAgent = "go-midjourney/0.0.0-dev"
)
type Option interface {
apply(*Client) error
}
type optionFunc func(*Client) error
func (fn optionFunc) apply(o *Client) error {
return fn(o)
}
func WithAuthToken(authToken string) Option {
return optionFunc(func(c *Client) error {
c.AuthToken = authToken
return nil
})
}
func WithAPIURL(baseURL string) Option {
return optionFunc(func(c *Client) error {
if !strings.HasSuffix(baseURL, "/") {
baseURL += "/"
}
u, err := url.Parse(baseURL)
if err != nil {
return err
}
c.APIURL = u
return nil
})
}
func WithHTTPClient(httpClient *http.Client) Option {
return optionFunc(func(c *Client) error {
c.HTTPClient = httpClient
return nil
})
}
func WithUserAgent(userAgent string) Option {
return optionFunc(func(c *Client) error {
c.UserAgent = userAgent
return nil
})
}
func WithLogger(logger zerolog.Logger) Option {
return optionFunc(func(c *Client) error {
c.Logger = logger
return nil
})
}
type HTTPClient interface {
Do(req *http.Request) (*http.Response, error)
}
type Client struct {
HTTPClient HTTPClient
APIURL *url.URL
AuthToken string
UserAgent string
Logger zerolog.Logger
}
func New(options ...Option) (*Client, error) {
c := &Client{
HTTPClient: http.DefaultClient,
APIURL: &DefaultAPIURL,
UserAgent: DefaultUserAgent,
Logger: zerolog.Nop(),
}
err := c.Set(options...)
return c, err
}
func (c *Client) Set(options ...Option) error {
for _, opt := range options {
err := opt.apply(c)
if err != nil {
return err
}
}
return nil
}
func (c *Client) Do(req *http.Request) (*http.Response, error) {
req.URL = c.APIURL.ResolveReference(req.URL)
c.Logger.Debug().Str("url", req.URL.String()).Msg("request")
req.Header.Set("Accept", "application/json")
if c.AuthToken != "" {
req.Header.Set(
"Cookie", "__Secure-next-auth.session-token="+c.AuthToken,
)
}
if c.UserAgent != "" {
req.Header.Set("User-Agent", c.UserAgent)
}
return c.HTTPClient.Do(req)
}