mirror of
https://github.com/FJurmanovic/sugarr.git
synced 2026-11-10 23:31:08 +00:00
112 lines
2.8 KiB
Go
112 lines
2.8 KiB
Go
package client
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"net/url"
|
|
"strconv"
|
|
|
|
"github.com/fjurmanovic/sugarr/internal/model"
|
|
"github.com/fjurmanovic/sugarr/internal/utl/configs"
|
|
)
|
|
|
|
const tmdbBaseURL = "https://api.themoviedb.org"
|
|
|
|
type TMDbClient struct {
|
|
apiKey string
|
|
http *http.Client
|
|
}
|
|
|
|
func NewTMDbClient(cfg *configs.Config) *TMDbClient {
|
|
return &TMDbClient{
|
|
apiKey: cfg.TMDbAPIKey,
|
|
http: &http.Client{},
|
|
}
|
|
}
|
|
|
|
type tmdbSearchResponse struct {
|
|
Results []tmdbMovieJSON `json:"results"`
|
|
}
|
|
|
|
type tmdbMovieJSON struct {
|
|
ID int `json:"id"`
|
|
Title string `json:"title"`
|
|
ReleaseDate string `json:"release_date"`
|
|
}
|
|
|
|
func (m tmdbMovieJSON) toModel() model.TMDbMovie {
|
|
year := 0
|
|
if len(m.ReleaseDate) >= 4 {
|
|
year, _ = strconv.Atoi(m.ReleaseDate[:4])
|
|
}
|
|
return model.TMDbMovie{ID: m.ID, Title: m.Title, Year: year}
|
|
}
|
|
|
|
func (c *TMDbClient) get(path string, params url.Values) (*http.Response, error) {
|
|
params.Set("api_key", c.apiKey)
|
|
u := fmt.Sprintf("%s%s?%s", tmdbBaseURL, path, params.Encode())
|
|
req, err := http.NewRequest(http.MethodGet, u, nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
req.Header.Set("Accept", "application/json")
|
|
resp, err := c.http.Do(req)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("tmdb request failed: %w", err)
|
|
}
|
|
if resp.StatusCode != http.StatusOK {
|
|
resp.Body.Close()
|
|
return nil, fmt.Errorf("tmdb returned status %d for %s", resp.StatusCode, path)
|
|
}
|
|
return resp, nil
|
|
}
|
|
|
|
func (c *TMDbClient) SearchMovie(title string, year int) (*model.TMDbMovie, error) {
|
|
params := url.Values{"query": {title}}
|
|
if year > 0 {
|
|
params.Set("year", strconv.Itoa(year))
|
|
}
|
|
resp, err := c.get("/3/search/movie", params)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
var result tmdbSearchResponse
|
|
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
|
|
return nil, fmt.Errorf("decoding tmdb search response: %w", err)
|
|
}
|
|
if len(result.Results) == 0 {
|
|
return nil, nil
|
|
}
|
|
m := result.Results[0].toModel()
|
|
return &m, nil
|
|
}
|
|
|
|
func (c *TMDbClient) getMovieList(path string) ([]model.TMDbMovie, error) {
|
|
resp, err := c.get(path, url.Values{})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
var result tmdbSearchResponse
|
|
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
|
|
return nil, fmt.Errorf("decoding tmdb response: %w", err)
|
|
}
|
|
movies := make([]model.TMDbMovie, 0, len(result.Results))
|
|
for _, r := range result.Results {
|
|
movies = append(movies, r.toModel())
|
|
}
|
|
return movies, nil
|
|
}
|
|
|
|
func (c *TMDbClient) GetSimilar(tmdbID int) ([]model.TMDbMovie, error) {
|
|
return c.getMovieList(fmt.Sprintf("/3/movie/%d/similar", tmdbID))
|
|
}
|
|
|
|
func (c *TMDbClient) GetRecommendations(tmdbID int) ([]model.TMDbMovie, error) {
|
|
return c.getMovieList(fmt.Sprintf("/3/movie/%d/recommendations", tmdbID))
|
|
}
|