media: add support for legacy tvdb api (#16)
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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"`
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
7
media/tvdb/config.go
Normal 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
58
media/tvdb/media.go
Normal 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
42
media/tvdb/struct.go
Normal 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
33
media/tvdb/tvdb.go
Normal 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,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user