mirror of
https://github.com/FJurmanovic/sugarr.git
synced 2026-11-11 15:51:09 +00:00
init
This commit is contained in:
111
internal/client/tmdb.go
Normal file
111
internal/client/tmdb.go
Normal file
@@ -0,0 +1,111 @@
|
||||
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))
|
||||
}
|
||||
Reference in New Issue
Block a user