initial code (#6)

* initial code commit
This commit is contained in:
l3uddz
2021-02-14 16:18:26 +00:00
committed by GitHub
parent 3f55336fbd
commit ce3807b819
53 changed files with 3694 additions and 0 deletions

7
media/omdb/config.go Normal file
View 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
View 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
View 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
View 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"`
}