34
media/client.go
Normal file
34
media/client.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package media
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/l3uddz/nabarr/logger"
|
||||
"github.com/l3uddz/nabarr/media/omdb"
|
||||
"github.com/l3uddz/nabarr/media/trakt"
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
type Client struct {
|
||||
trakt *trakt.Client
|
||||
omdb *omdb.Client
|
||||
|
||||
log zerolog.Logger
|
||||
}
|
||||
|
||||
func New(cfg *Config) (*Client, error) {
|
||||
// trakt
|
||||
if cfg.Trakt.ClientId == "" {
|
||||
return nil, fmt.Errorf("trakt: no client_id specified")
|
||||
}
|
||||
t := trakt.New(&cfg.Trakt)
|
||||
|
||||
// omdb
|
||||
o := omdb.New(&cfg.Omdb)
|
||||
|
||||
return &Client{
|
||||
trakt: t,
|
||||
omdb: o,
|
||||
|
||||
log: logger.New(cfg.Verbosity).With().Logger(),
|
||||
}, nil
|
||||
}
|
||||
13
media/config.go
Normal file
13
media/config.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package media
|
||||
|
||||
import (
|
||||
"github.com/l3uddz/nabarr/media/omdb"
|
||||
"github.com/l3uddz/nabarr/media/trakt"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Trakt trakt.Config `yaml:"trakt"`
|
||||
Omdb omdb.Config `yaml:"omdb"`
|
||||
|
||||
Verbosity string `yaml:"verbosity,omitempty"`
|
||||
}
|
||||
7
media/error.go
Normal file
7
media/error.go
Normal file
@@ -0,0 +1,7 @@
|
||||
package media
|
||||
|
||||
import "errors"
|
||||
|
||||
var (
|
||||
ErrItemNotFound = errors.New("not found")
|
||||
)
|
||||
58
media/movie.go
Normal file
58
media/movie.go
Normal file
@@ -0,0 +1,58 @@
|
||||
package media
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/l3uddz/nabarr/media/trakt"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
func (c *Client) GetMovieInfo(item *FeedItem) (*Item, error) {
|
||||
// lookup on trakt
|
||||
t, err := c.trakt.GetMovie(item.ImdbId)
|
||||
if err != nil {
|
||||
if errors.Is(err, trakt.ErrItemNotFound) {
|
||||
return nil, fmt.Errorf("trakt: get movie: movie with imdbId %q: %w", item.ImdbId, ErrItemNotFound)
|
||||
}
|
||||
return nil, fmt.Errorf("trakt: get movie: movie with imdbId %q: %w", item.ImdbId, err)
|
||||
}
|
||||
|
||||
// transform trakt info
|
||||
date, err := time.Parse("2006-01-02", t.Released)
|
||||
if err != nil {
|
||||
date = time.Time{}
|
||||
}
|
||||
|
||||
mi := &Item{
|
||||
TvdbId: "",
|
||||
TmdbId: strconv.Itoa(t.Ids.Tmdb),
|
||||
ImdbId: t.Ids.Imdb,
|
||||
Slug: t.Ids.Slug,
|
||||
Title: t.Title,
|
||||
FeedTitle: item.Title,
|
||||
Summary: t.Overview,
|
||||
Country: []string{t.Country},
|
||||
Network: "",
|
||||
Date: date,
|
||||
Year: date.Year(),
|
||||
Runtime: t.Runtime,
|
||||
Rating: t.Rating,
|
||||
Votes: t.Votes,
|
||||
Status: t.Status,
|
||||
Genres: t.Genres,
|
||||
Languages: []string{t.Language},
|
||||
}
|
||||
|
||||
// omdb
|
||||
if oi, err := c.omdb.GetItem(t.Ids.Imdb); err != nil {
|
||||
c.log.Debug().
|
||||
Err(err).
|
||||
Str("imdb_id", t.Ids.Imdb).
|
||||
Msg("Item was not found on omdb")
|
||||
} else if oi != nil {
|
||||
mi.Omdb = *oi
|
||||
}
|
||||
|
||||
return mi, nil
|
||||
}
|
||||
7
media/omdb/config.go
Normal file
7
media/omdb/config.go
Normal file
@@ -0,0 +1,7 @@
|
||||
package omdb
|
||||
|
||||
type Config struct {
|
||||
ApiKey string `yaml:"api_key"`
|
||||
|
||||
Verbosity string `yaml:"verbosity,omitempty"`
|
||||
}
|
||||
72
media/omdb/media.go
Normal file
72
media/omdb/media.go
Normal file
@@ -0,0 +1,72 @@
|
||||
package omdb
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/l3uddz/nabarr/util"
|
||||
"github.com/lucperkins/rek"
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrItemNotFound = errors.New("not found")
|
||||
)
|
||||
|
||||
func (c *Client) GetItem(imdbId string) (*Item, error) {
|
||||
// empty item when appropriate
|
||||
if c.apiKey == "" || imdbId == "" {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// prepare request
|
||||
reqUrl, err := util.URLWithQuery(c.apiURL, url.Values{
|
||||
"apikey": []string{c.apiKey},
|
||||
"i": []string{imdbId}})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("generate lookup request url: %w", err)
|
||||
}
|
||||
|
||||
c.log.Trace().
|
||||
Str("url", reqUrl).
|
||||
Msg("Searching omdb")
|
||||
|
||||
// send request
|
||||
c.rl.Take()
|
||||
resp, err := rek.Get(reqUrl, rek.Timeout(c.apiTimeout))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("request lookup: %w", err)
|
||||
}
|
||||
defer resp.Body().Close()
|
||||
|
||||
// validate response
|
||||
if resp.StatusCode() != 200 {
|
||||
return nil, fmt.Errorf("validate lookup response: %s", resp.Status())
|
||||
}
|
||||
|
||||
// decode response
|
||||
b := new(lookupResponse)
|
||||
if err := json.NewDecoder(resp.Body()).Decode(b); err != nil {
|
||||
return nil, fmt.Errorf("decode lookup response: %w", err)
|
||||
}
|
||||
|
||||
if b.Title == "" {
|
||||
return nil, fmt.Errorf("item with imdbId: %v: %w", imdbId, ErrItemNotFound)
|
||||
}
|
||||
|
||||
// transform response
|
||||
rt := 0
|
||||
for _, rating := range b.Ratings {
|
||||
if strings.EqualFold(rating.Source, "Rotten Tomatoes") {
|
||||
rt = util.Atoi(strings.TrimSuffix(rating.Value, "%"), 0)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return &Item{
|
||||
Metascore: util.Atoi(b.Metascore, 0),
|
||||
RottenTomatoes: rt,
|
||||
ImdbRating: util.Atof64(b.ImdbRating, 0.0),
|
||||
}, nil
|
||||
}
|
||||
28
media/omdb/omdb.go
Normal file
28
media/omdb/omdb.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package omdb
|
||||
|
||||
import (
|
||||
"github.com/l3uddz/nabarr/logger"
|
||||
"github.com/rs/zerolog"
|
||||
"go.uber.org/ratelimit"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Client struct {
|
||||
apiKey string
|
||||
log zerolog.Logger
|
||||
rl ratelimit.Limiter
|
||||
|
||||
apiURL string
|
||||
apiTimeout time.Duration
|
||||
}
|
||||
|
||||
func New(cfg *Config) *Client {
|
||||
return &Client{
|
||||
apiKey: cfg.ApiKey,
|
||||
log: logger.New(cfg.Verbosity).With().Logger(),
|
||||
rl: ratelimit.New(1, ratelimit.WithoutSlack),
|
||||
|
||||
apiURL: "https://www.omdbapi.com",
|
||||
apiTimeout: 30 * time.Second,
|
||||
}
|
||||
}
|
||||
40
media/omdb/struct.go
Normal file
40
media/omdb/struct.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package omdb
|
||||
|
||||
type rating struct {
|
||||
Source string `json:"Source,omitempty"`
|
||||
Value string `json:"Value,omitempty"`
|
||||
}
|
||||
|
||||
type lookupResponse struct {
|
||||
Title string `json:"Title,omitempty"`
|
||||
Year string `json:"Year,omitempty"`
|
||||
Rated string `json:"Rated,omitempty"`
|
||||
Released string `json:"Released,omitempty"`
|
||||
Runtime string `json:"Runtime,omitempty"`
|
||||
Genre string `json:"Genre,omitempty"`
|
||||
Director string `json:"Director,omitempty"`
|
||||
Writer string `json:"Writer,omitempty"`
|
||||
Actors string `json:"Actors,omitempty"`
|
||||
Plot string `json:"Plot,omitempty"`
|
||||
Language string `json:"Language,omitempty"`
|
||||
Country string `json:"Country,omitempty"`
|
||||
Awards string `json:"Awards,omitempty"`
|
||||
Poster string `json:"Poster,omitempty"`
|
||||
Ratings []rating `json:"Ratings,omitempty"`
|
||||
Metascore string `json:"Metascore,omitempty"`
|
||||
ImdbRating string `json:"imdbRating,omitempty"`
|
||||
ImdbVotes string `json:"imdbVotes,omitempty"`
|
||||
ImdbID string `json:"imdbID,omitempty"`
|
||||
Type string `json:"Type,omitempty"`
|
||||
DVD string `json:"DVD,omitempty"`
|
||||
BoxOffice string `json:"BoxOffice,omitempty"`
|
||||
Production string `json:"Production,omitempty"`
|
||||
Website string `json:"Website,omitempty"`
|
||||
Response string `json:"Response,omitempty"`
|
||||
}
|
||||
|
||||
type Item struct {
|
||||
Metascore int `json:"Metascore,omitempty"`
|
||||
RottenTomatoes int `json:"RottenTomatoes,omitempty"`
|
||||
ImdbRating float64 `json:"ImdbRating,omitempty"`
|
||||
}
|
||||
53
media/show.go
Normal file
53
media/show.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package media
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/l3uddz/nabarr/media/trakt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func (c *Client) GetShowInfo(item *FeedItem) (*Item, error) {
|
||||
// lookup on trakt
|
||||
t, err := c.trakt.GetShow(item.TvdbId)
|
||||
if err != nil {
|
||||
if errors.Is(err, trakt.ErrItemNotFound) {
|
||||
return nil, fmt.Errorf("trakt: get show: show with tvdbId %q: %w", item.TvdbId, ErrItemNotFound)
|
||||
}
|
||||
return nil, fmt.Errorf("trakt: get show: show with tvdbId %q: %w", item.TvdbId, err)
|
||||
}
|
||||
|
||||
// transform trakt info to MediaItem
|
||||
mi := &Item{
|
||||
TvdbId: strconv.Itoa(t.Ids.Tvdb),
|
||||
TmdbId: strconv.Itoa(t.Ids.Tmdb),
|
||||
ImdbId: t.Ids.Imdb,
|
||||
Slug: t.Ids.Slug,
|
||||
Title: t.Title,
|
||||
FeedTitle: item.Title,
|
||||
Summary: t.Overview,
|
||||
Country: []string{t.Country},
|
||||
Network: t.Network,
|
||||
Date: t.FirstAired,
|
||||
Year: t.FirstAired.Year(),
|
||||
Runtime: t.Runtime,
|
||||
Rating: t.Rating,
|
||||
Votes: t.Votes,
|
||||
Status: t.Status,
|
||||
Genres: t.Genres,
|
||||
Languages: []string{t.Language},
|
||||
AiredEpisodes: t.AiredEpisodes,
|
||||
}
|
||||
|
||||
// omdb
|
||||
if oi, err := c.omdb.GetItem(t.Ids.Imdb); err != nil {
|
||||
c.log.Debug().
|
||||
Err(err).
|
||||
Str("imdb_id", t.Ids.Imdb).
|
||||
Msg("Item was not found on omdb")
|
||||
} else if oi != nil {
|
||||
mi.Omdb = *oi
|
||||
}
|
||||
|
||||
return mi, nil
|
||||
}
|
||||
95
media/struct.go
Normal file
95
media/struct.go
Normal file
@@ -0,0 +1,95 @@
|
||||
package media
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"github.com/l3uddz/nabarr/media/omdb"
|
||||
"github.com/pkg/errors"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Item struct {
|
||||
TvdbId string `json:"TvdbId,omitempty"`
|
||||
TmdbId string `json:"TmdbId,omitempty"`
|
||||
ImdbId string `json:"ImdbId,omitempty"`
|
||||
Slug string `json:"Slug,omitempty"`
|
||||
FeedTitle string `json:"FeedTitle,omitempty"`
|
||||
Title string `json:"Title,omitempty"`
|
||||
Summary string `json:"Summary,omitempty"`
|
||||
Country []string `json:"Country,omitempty"`
|
||||
Network string `json:"Network,omitempty"`
|
||||
Date time.Time `json:"Date"`
|
||||
Year int `json:"Year,omitempty"`
|
||||
Runtime int `json:"Runtime,omitempty"`
|
||||
Rating float64 `json:"Rating,omitempty"`
|
||||
Votes int `json:"Votes,omitempty"`
|
||||
Status string `json:"Status,omitempty"`
|
||||
Genres []string `json:"Genres,omitempty"`
|
||||
Languages []string `json:"Languages,omitempty"`
|
||||
AiredEpisodes int `json:"AiredEpisodes,omitempty"`
|
||||
|
||||
// additional media provider data
|
||||
Omdb omdb.Item `json:"Omdb,omitempty"`
|
||||
}
|
||||
|
||||
type Rss struct {
|
||||
Channel struct {
|
||||
Items []FeedItem `xml:"item"`
|
||||
} `xml:"channel"`
|
||||
}
|
||||
|
||||
type FeedItem struct {
|
||||
Title string `xml:"title,omitempty"`
|
||||
Category string `xml:"category,omitempty"`
|
||||
GUID string `xml:"guid,omitempty"`
|
||||
PubDate Time `xml:"pubDate,omitempty"`
|
||||
|
||||
// set by processor
|
||||
Feed string
|
||||
|
||||
// attributes
|
||||
Language string
|
||||
TvdbId string `xml:"tvdb,omitempty"`
|
||||
TvMazeId string
|
||||
ImdbId string `xml:"imdb,omitempty"`
|
||||
|
||||
Attributes []struct {
|
||||
XMLName xml.Name
|
||||
Name string `xml:"name,attr"`
|
||||
Value string `xml:"value,attr"`
|
||||
} `xml:"attr"`
|
||||
}
|
||||
|
||||
// Time credits: https://github.com/mrobinsn/go-newznab/blob/cd89d9c56447859fa1298dc9a0053c92c45ac7ef/newznab/structs.go#L150
|
||||
type Time struct {
|
||||
time.Time
|
||||
}
|
||||
|
||||
func (t *Time) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
||||
if err := e.EncodeToken(start); err != nil {
|
||||
return errors.Wrap(err, "failed to encode xml token")
|
||||
}
|
||||
if err := e.EncodeToken(xml.CharData([]byte(t.UTC().Format(time.RFC1123Z)))); err != nil {
|
||||
return errors.Wrap(err, "failed to encode xml token")
|
||||
}
|
||||
if err := e.EncodeToken(xml.EndElement{Name: start.Name}); err != nil {
|
||||
return errors.Wrap(err, "failed to encode xml token")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *Time) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
||||
var raw string
|
||||
|
||||
err := d.DecodeElement(&raw, &start)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
date, err := time.Parse(time.RFC1123Z, raw)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*t = Time{date}
|
||||
return nil
|
||||
}
|
||||
7
media/trakt/config.go
Normal file
7
media/trakt/config.go
Normal file
@@ -0,0 +1,7 @@
|
||||
package trakt
|
||||
|
||||
type Config struct {
|
||||
ClientId string `yaml:"client_id"`
|
||||
|
||||
Verbosity string `yaml:"verbosity,omitempty"`
|
||||
}
|
||||
96
media/trakt/media.go
Normal file
96
media/trakt/media.go
Normal file
@@ -0,0 +1,96 @@
|
||||
package trakt
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/l3uddz/nabarr/util"
|
||||
"github.com/lucperkins/rek"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrItemNotFound = errors.New("not found")
|
||||
)
|
||||
|
||||
func (c *Client) GetShow(tvdbId string) (*Show, error) {
|
||||
// prepare request
|
||||
reqUrl, err := util.URLWithQuery(util.JoinURL(c.apiURL, fmt.Sprintf("/search/tvdb/%s", tvdbId)),
|
||||
url.Values{
|
||||
"type": []string{"show"},
|
||||
"extended": []string{"full"}})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("generate lookup show request url: %w", err)
|
||||
}
|
||||
|
||||
c.log.Trace().
|
||||
Str("url", reqUrl).
|
||||
Msg("Searching trakt")
|
||||
|
||||
// send request
|
||||
c.rl.Take()
|
||||
resp, err := rek.Get(reqUrl, rek.Headers(c.getAuthHeaders()), rek.Timeout(c.apiTimeout))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("request show: %w", err)
|
||||
}
|
||||
defer resp.Body().Close()
|
||||
|
||||
// validate response
|
||||
if resp.StatusCode() != 200 {
|
||||
return nil, fmt.Errorf("validate show response: %s", resp.Status())
|
||||
}
|
||||
|
||||
// decode response
|
||||
b := new([]struct{ Show Show })
|
||||
if err := json.NewDecoder(resp.Body()).Decode(b); err != nil {
|
||||
return nil, fmt.Errorf("decode show response: %w", err)
|
||||
}
|
||||
|
||||
if len(*b) < 1 {
|
||||
return nil, ErrItemNotFound
|
||||
}
|
||||
|
||||
// translate response
|
||||
return &(*b)[0].Show, nil
|
||||
}
|
||||
|
||||
func (c *Client) GetMovie(imdbId string) (*Movie, error) {
|
||||
// prepare request
|
||||
reqUrl, err := util.URLWithQuery(util.JoinURL(c.apiURL, fmt.Sprintf("/search/imdb/%s", imdbId)),
|
||||
url.Values{
|
||||
"type": []string{"movie"},
|
||||
"extended": []string{"full"}})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("generate lookup movie request url: %w", err)
|
||||
}
|
||||
|
||||
c.log.Trace().
|
||||
Str("url", reqUrl).
|
||||
Msg("Searching trakt")
|
||||
|
||||
// send request
|
||||
c.rl.Take()
|
||||
resp, err := rek.Get(reqUrl, rek.Headers(c.getAuthHeaders()), rek.Timeout(c.apiTimeout))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("request movie: %w", err)
|
||||
}
|
||||
defer resp.Body().Close()
|
||||
|
||||
// validate response
|
||||
if resp.StatusCode() != 200 {
|
||||
return nil, fmt.Errorf("validate movie response: %s", resp.Status())
|
||||
}
|
||||
|
||||
// decode response
|
||||
b := new([]struct{ Movie Movie })
|
||||
if err := json.NewDecoder(resp.Body()).Decode(b); err != nil {
|
||||
return nil, fmt.Errorf("decode movie response: %w", err)
|
||||
}
|
||||
|
||||
if len(*b) < 1 {
|
||||
return nil, ErrItemNotFound
|
||||
}
|
||||
|
||||
// translate response
|
||||
return &(*b)[0].Movie, nil
|
||||
}
|
||||
67
media/trakt/struct.go
Normal file
67
media/trakt/struct.go
Normal file
@@ -0,0 +1,67 @@
|
||||
package trakt
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type ShowIds struct {
|
||||
Trakt int `json:"trakt"`
|
||||
Slug string `json:"slug"`
|
||||
Tvdb int `json:"tvdb"`
|
||||
Imdb string `json:"imdb"`
|
||||
Tmdb int `json:"tmdb"`
|
||||
}
|
||||
|
||||
type MovieIds struct {
|
||||
Trakt int `json:"trakt"`
|
||||
Slug string `json:"slug"`
|
||||
Imdb string `json:"imdb"`
|
||||
Tmdb int `json:"tmdb"`
|
||||
}
|
||||
|
||||
type Show struct {
|
||||
Type string `json:"type"`
|
||||
Title string `json:"title"`
|
||||
Year int `json:"year"`
|
||||
Ids ShowIds `json:"ids"`
|
||||
Overview string `json:"overview"`
|
||||
FirstAired time.Time `json:"first_aired"`
|
||||
Runtime int `json:"runtime"`
|
||||
Certification string `json:"certification"`
|
||||
Network string `json:"network"`
|
||||
Country string `json:"country"`
|
||||
Trailer string `json:"trailer"`
|
||||
Homepage string `json:"homepage"`
|
||||
Status string `json:"status"`
|
||||
Rating float64 `json:"rating"`
|
||||
Votes int `json:"votes"`
|
||||
CommentCount int `json:"comment_count"`
|
||||
Language string `json:"language"`
|
||||
AvailableTranslations []string `json:"available_translations"`
|
||||
Genres []string `json:"genres"`
|
||||
AiredEpisodes int `json:"aired_episodes"`
|
||||
Character string `json:"character"`
|
||||
}
|
||||
|
||||
type Movie struct {
|
||||
Type string `json:"type"`
|
||||
Title string `json:"title"`
|
||||
Year int `json:"year"`
|
||||
Ids MovieIds `json:"ids"`
|
||||
Tagline string `json:"tagline"`
|
||||
Overview string `json:"overview"`
|
||||
Released string `json:"released"`
|
||||
Runtime int `json:"runtime"`
|
||||
Country string `json:"country"`
|
||||
Trailer string `json:"trailer"`
|
||||
Homepage string `json:"homepage"`
|
||||
Status string `json:"status"`
|
||||
Rating float64 `json:"rating"`
|
||||
Votes int `json:"votes"`
|
||||
CommentCount int `json:"comment_count"`
|
||||
Language string `json:"language"`
|
||||
AvailableTranslations []string `json:"available_translations"`
|
||||
Genres []string `json:"genres"`
|
||||
Certification string `json:"certification"`
|
||||
Character string `json:"character"`
|
||||
}
|
||||
35
media/trakt/trakt.go
Normal file
35
media/trakt/trakt.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package trakt
|
||||
|
||||
import (
|
||||
"github.com/l3uddz/nabarr/logger"
|
||||
"github.com/rs/zerolog"
|
||||
"go.uber.org/ratelimit"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Client struct {
|
||||
clientId string
|
||||
log zerolog.Logger
|
||||
rl ratelimit.Limiter
|
||||
|
||||
apiURL string
|
||||
apiTimeout time.Duration
|
||||
}
|
||||
|
||||
func New(cfg *Config) *Client {
|
||||
return &Client{
|
||||
clientId: cfg.ClientId,
|
||||
log: logger.New(cfg.Verbosity).With().Logger(),
|
||||
rl: ratelimit.New(1, ratelimit.WithoutSlack),
|
||||
|
||||
apiURL: "https://api.trakt.tv",
|
||||
apiTimeout: 30 * time.Second,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) getAuthHeaders() map[string]string {
|
||||
return map[string]string{
|
||||
"trakt-api-key": c.clientId,
|
||||
"trakt-api-version": "2",
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user