media: add support for legacy tvdb api (#16)

This commit is contained in:
l3uddz
2021-02-19 23:31:23 +00:00
committed by GitHub
parent 5b179ed8dc
commit e5bcb5b381
8 changed files with 160 additions and 7 deletions

View File

@@ -5,29 +5,28 @@ import (
"github.com/l3uddz/nabarr/logger"
"github.com/l3uddz/nabarr/media/omdb"
"github.com/l3uddz/nabarr/media/trakt"
"github.com/l3uddz/nabarr/media/tvdb"
"github.com/rs/zerolog"
)
type Client struct {
trakt *trakt.Client
omdb *omdb.Client
tvdb *tvdb.Client
log zerolog.Logger
}
func New(cfg *Config) (*Client, error) {
// trakt
// validate trakt configured (it is mandatory)
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,
trakt: trakt.New(&cfg.Trakt),
omdb: omdb.New(&cfg.Omdb),
tvdb: tvdb.New(&cfg.Tvdb),
log: logger.New(cfg.Verbosity).With().Logger(),
}, nil

View File

@@ -3,11 +3,13 @@ package media
import (
"github.com/l3uddz/nabarr/media/omdb"
"github.com/l3uddz/nabarr/media/trakt"
"github.com/l3uddz/nabarr/media/tvdb"
)
type Config struct {
Trakt trakt.Config `yaml:"trakt"`
Omdb omdb.Config `yaml:"omdb"`
Tvdb tvdb.Config `yaml:"tvdb"`
Verbosity string `yaml:"verbosity,omitempty"`
}

View File

@@ -49,5 +49,15 @@ func (c *Client) GetShowInfo(item *FeedItem) (*Item, error) {
mi.Omdb = *oi
}
// tvdb
if ti, err := c.tvdb.GetItem(strconv.Itoa(t.Ids.Tvdb)); err != nil {
c.log.Debug().
Err(err).
Int("tvdb_id", t.Ids.Tvdb).
Msg("Item was not found on tvdb")
} else if ti != nil {
mi.Tvdb = *ti
}
return mi, nil
}

View File

@@ -3,6 +3,7 @@ package media
import (
"encoding/xml"
"github.com/l3uddz/nabarr/media/omdb"
"github.com/l3uddz/nabarr/media/tvdb"
"github.com/pkg/errors"
"time"
)
@@ -29,6 +30,7 @@ type Item struct {
// additional media provider data
Omdb omdb.Item `json:"Omdb,omitempty"`
Tvdb tvdb.Item `json:"Tvdb,omitempty"`
}
type Rss struct {

7
media/tvdb/config.go Normal file
View File

@@ -0,0 +1,7 @@
package tvdb
type Config struct {
ApiKey string `yaml:"api_key"`
Verbosity string `yaml:"verbosity,omitempty"`
}

58
media/tvdb/media.go Normal file
View File

@@ -0,0 +1,58 @@
package tvdb
import (
"encoding/json"
"errors"
"fmt"
"github.com/l3uddz/nabarr/util"
"github.com/lucperkins/rek"
)
var (
ErrItemNotFound = errors.New("not found")
)
func (c *Client) GetItem(tvdbId string) (*Item, error) {
// empty item when appropriate
if c.apiKey == "" || tvdbId == "" {
return nil, nil
}
// prepare request
reqUrl := util.JoinURL(c.apiURL, "series", tvdbId)
c.log.Trace().
Str("url", reqUrl).
Msg("Searching tvdb")
// send request
c.rl.Take()
resp, err := rek.Get(reqUrl, rek.Headers(c.apiHeaders), 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.Data.SeriesName == "" {
return nil, fmt.Errorf("item with imdbId: %v: %w", tvdbId, ErrItemNotFound)
}
return &Item{
Runtime: util.Atoi(b.Data.Runtime, 0),
Language: b.Data.Language,
Genre: b.Data.Genre,
AirsDayOfWeek: b.Data.AirsDayOfWeek,
SiteRating: b.Data.SiteRating,
SiteRatingCount: b.Data.SiteRatingCount,
}, nil
}

42
media/tvdb/struct.go Normal file
View File

@@ -0,0 +1,42 @@
package tvdb
type lookupResponse struct {
Data struct {
Id int `json:"id,omitempty"`
SeriesId string `json:"seriesId,omitempty"`
SeriesName string `json:"seriesName,omitempty"`
Aliases []interface{} `json:"aliases,omitempty"`
Season string `json:"season,omitempty"`
Poster string `json:"poster,omitempty"`
Banner string `json:"banner,omitempty"`
Fanart string `json:"fanart,omitempty"`
Status string `json:"status,omitempty"`
FirstAired string `json:"firstAired,omitempty"`
Network string `json:"network,omitempty"`
NetworkId string `json:"networkId,omitempty"`
Runtime string `json:"runtime,omitempty"`
Language string `json:"language,omitempty"`
Genre []string `json:"genre,omitempty"`
Overview string `json:"overview,omitempty"`
LastUpdated int `json:"lastUpdated,omitempty"`
AirsDayOfWeek string `json:"airsDayOfWeek,omitempty"`
AirsTime string `json:"airsTime,omitempty"`
Rating interface{} `json:"rating,omitempty"`
ImdbId string `json:"imdbId,omitempty"`
Zap2ItId string `json:"zap2itId,omitempty"`
Added string `json:"added,omitempty"`
AddedBy int `json:"addedBy,omitempty"`
SiteRating float64 `json:"siteRating,omitempty"`
SiteRatingCount int `json:"siteRatingCount,omitempty"`
Slug string `json:"slug,omitempty"`
} `json:"data"`
}
type Item struct {
Runtime int `json:"Runtime,omitempty"`
Language string `json:"Language,omitempty"`
Genre []string `json:"Genre,omitempty"`
AirsDayOfWeek string `json:"AirsDayOfWeek,omitempty"`
SiteRating float64 `json:"SiteRating,omitempty"`
SiteRatingCount int `json:"SiteRatingCount,omitempty"`
}

33
media/tvdb/tvdb.go Normal file
View File

@@ -0,0 +1,33 @@
package tvdb
import (
"fmt"
"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
apiHeaders map[string]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://api.thetvdb.com",
apiHeaders: map[string]string{
"Authorization": fmt.Sprintf("Bearer %s", cfg.ApiKey),
},
apiTimeout: 30 * time.Second,
}
}