Documentation
¶
Overview ¶
Package tmdb is a TMDB API v3 client with rate limiting, retries, request coalescing and an ETag/TTL response cache.
Index ¶
- Constants
- Variables
- func IsBearerKey(key string) bool
- func ParseDate(s string) time.Time
- func ResolveKey(cfg config.Catalog) string
- type AltTitle
- type AltTitles
- type CastMember
- type Client
- func (c *Client) ArtworkVariants(ctx context.Context, t *core.Title, language string) (*Images, error)
- func (c *Client) CachedArtworkVariants(t *core.Title, language string) (*Images, bool)
- func (c *Client) Close()
- func (c *Client) CollectionDetails(ctx context.Context, id int64) (*CollectionDetails, error)
- func (c *Client) Configuration(ctx context.Context) (*Configuration, error)
- func (c *Client) DiscoverMovies(ctx context.Context, p DiscoverParams) (*Paged[Movie], error)
- func (c *Client) DiscoverTV(ctx context.Context, p DiscoverParams) (*Paged[TVShow], error)
- func (c *Client) EpisodeDetails(ctx context.Context, tvID int64, season, episode int) (*Episode, error)
- func (c *Client) EpisodeExternalIDs(ctx context.Context, tvID int64, season, episode int) (*ExternalIDs, error)
- func (c *Client) EpisodeGroup(ctx context.Context, id string) (*EpisodeGroup, error)
- func (c *Client) EpisodeGroups(ctx context.Context, show int64) ([]EpisodeGroupSummary, error)
- func (c *Client) EpisodeVideos(ctx context.Context, tvID int64, season, episode int, lang string) ([]Video, error)
- func (c *Client) FindByExternalID(ctx context.Context, source, id string) (*FindResult, error)
- func (c *Client) Genres(ctx context.Context, mediaType string) ([]Genre, error)
- func (c *Client) GetJSON(ctx context.Context, path string, q url.Values, out any) error
- func (c *Client) HasKey() bool
- func (c *Client) ImageURL(path, size string) string
- func (c *Client) ImageURLFunc() core.ImageURLFunc
- func (c *Client) Language() string
- func (c *Client) Localized(ctx context.Context, t *core.Title, language string) (*core.Title, error)
- func (c *Client) MovieDetails(ctx context.Context, id int64) (*MovieDetails, error)
- func (c *Client) MovieDetailsFresh(ctx context.Context, id int64) (*MovieDetails, error)
- func (c *Client) MovieList(ctx context.Context, list string, page int) (*Paged[Movie], error)
- func (c *Client) MovieRecommendations(ctx context.Context, id int64, page int) (*Paged[Movie], error)
- func (c *Client) MovieReleaseDates(ctx context.Context, id int64) (*ReleaseDates, error)
- func (c *Client) MovieSimilar(ctx context.Context, id int64, page int) (*Paged[Movie], error)
- func (c *Client) MovieVideos(ctx context.Context, id int64, lang string) ([]Video, error)
- func (c *Client) PersonCombinedCredits(ctx context.Context, id int64) (*PersonCombinedCredits, error)
- func (c *Client) PersonDetails(ctx context.Context, id int64) (*Person, error)
- func (c *Client) RateLimit() (perSec float64, burst int)
- func (c *Client) Region() string
- func (c *Client) SearchMovies(ctx context.Context, query string, page int) (*Paged[Movie], error)
- func (c *Client) SearchMulti(ctx context.Context, query string, page int) (*Paged[MultiResult], error)
- func (c *Client) SearchTV(ctx context.Context, query string, page int) (*Paged[TVShow], error)
- func (c *Client) SeasonDetails(ctx context.Context, tvID int64, season int) (*SeasonDetails, error)
- func (c *Client) SeasonVideos(ctx context.Context, tvID int64, season int, lang string) ([]Video, error)
- func (c *Client) SetConfiguration(cfg *Configuration)
- func (c *Client) SetRateShare(nodes int)
- func (c *Client) TVContentRatings(ctx context.Context, id int64) (*ContentRatings, error)
- func (c *Client) TVDetails(ctx context.Context, id int64) (*TVDetails, error)
- func (c *Client) TVDetailsFresh(ctx context.Context, id int64) (*TVDetails, error)
- func (c *Client) TVList(ctx context.Context, list string, page int) (*Paged[TVShow], error)
- func (c *Client) TVRecommendations(ctx context.Context, id int64, page int) (*Paged[TVShow], error)
- func (c *Client) TVSimilar(ctx context.Context, id int64, page int) (*Paged[TVShow], error)
- func (c *Client) TVVideos(ctx context.Context, id int64, lang string) ([]Video, error)
- func (c *Client) TrendingAll(ctx context.Context, window string, page int) (*Paged[MultiResult], error)
- func (c *Client) TrendingMovies(ctx context.Context, window string, page int) (*Paged[Movie], error)
- func (c *Client) TrendingTV(ctx context.Context, window string, page int) (*Paged[TVShow], error)
- func (c *Client) UpdateConfig(cfg config.Catalog)
- type CollectionDetails
- type CollectionRef
- type Company
- type Configuration
- type ContentRatings
- type Country
- type Credits
- type DiscoverParams
- type Episode
- type EpisodeGroup
- type EpisodeGroupSummary
- type EpisodeSubgroup
- type ExternalIDs
- type FindResult
- type Genre
- type GenreList
- type HTTPError
- type ImageFile
- type Images
- type Keyword
- type Keywords
- type Language
- type Movie
- type MovieDetails
- type MultiResult
- type Network
- type Option
- type OrderedEpisode
- type Paged
- type Person
- type PersonCombinedCredits
- type PersonCredit
- type ReleaseDateEntry
- type ReleaseDates
- type SeasonDetails
- type SeasonSummary
- type TVDetails
- type TVShow
- type Video
- type Videos
Constants ¶
const ( VideoTrailer = "Trailer" VideoClip = "Clip" VideoFeaturette = "Featurette" VideoBehindTheScenes = "Behind the Scenes" VideoBloopers = "Bloopers" )
Video types TMDB returns from /videos endpoints.
const DefaultBaseURL = "https://api.themoviedb.org/3"
const MinClusterRate = 5
MinClusterRate is the floor, in requests per second, of a node's TMDB rate when a cluster divides the per-key budget (SetRateShare).
Variables ¶
var BundledKey string
BundledKey is set at build time via -ldflags "-X github.com/braedonsaunders/ether/internal/tmdb.BundledKey=...". Never commit a real key here.
var ErrNoKey = errors.New("tmdb: no API key configured")
ErrNoKey is returned when no TMDB key is configured or bundled.
ErrUnavailable is returned without contacting TMDB while the circuit breaker is open: recent requests failed at the transport or with exhausted 429/5xx retries.
Functions ¶
func IsBearerKey ¶
IsBearerKey reports whether key looks like a v4 read-access token (JWT) rather than a 32-char v3 api_key.
func ResolveKey ¶
ResolveKey picks the owner override, else the bundled key.
Types ¶
type AltTitle ¶ added in v0.3.0
type AltTitle struct {
Country string `json:"iso_3166_1"`
Title string `json:"title"`
Type string `json:"type"`
}
AltTitle is one alternative title.
type AltTitles ¶ added in v0.3.0
AltTitles is the alternative_titles appendix: other names a title goes by (romanized originals such as "Sousou no Frieren", regional and working titles). Movies list them under titles, TV under results.
type CastMember ¶
type CastMember struct {
ID int64 `json:"id"`
Name string `json:"name"`
Character string `json:"character"`
Job string `json:"job"`
Department string `json:"department"`
Order int `json:"order"`
ProfilePath string `json:"profile_path"`
// aggregate credits
Roles []struct {
Character string `json:"character"`
} `json:"roles"`
Jobs []struct {
Job string `json:"job"`
} `json:"jobs"`
}
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is a TMDB API client. Safe for concurrent use.
func NewFromConfig ¶
NewFromConfig creates a client from catalogue config, falling back to BundledKey.
func (*Client) ArtworkVariants ¶
func (*Client) CachedArtworkVariants ¶ added in v0.3.0
CachedArtworkVariants returns only fresh cached data. It never contacts TMDB, waits for an in-flight fetch, or exposes stale data as authoritative. A miss can be filled separately using ArtworkVariants.
func (*Client) Close ¶
func (c *Client) Close()
Close releases the client (the rate limiter has no goroutine; Close is kept for callers that own the client).
func (*Client) CollectionDetails ¶
CollectionDetails fetches a franchise collection.
func (*Client) Configuration ¶
func (c *Client) Configuration(ctx context.Context) (*Configuration, error)
Configuration fetches /configuration (cached for ImageURL too).
func (*Client) DiscoverMovies ¶
DiscoverMovies pages /discover/movie.
func (*Client) DiscoverTV ¶
DiscoverTV pages /discover/tv.
func (*Client) EpisodeDetails ¶
func (c *Client) EpisodeDetails(ctx context.Context, tvID int64, season, episode int) (*Episode, error)
EpisodeDetails fetches one episode.
func (*Client) EpisodeExternalIDs ¶
func (c *Client) EpisodeExternalIDs(ctx context.Context, tvID int64, season, episode int) (*ExternalIDs, error)
EpisodeExternalIDs fetches external ids for one episode.
func (*Client) EpisodeGroup ¶
func (*Client) EpisodeGroups ¶
func (*Client) EpisodeVideos ¶
func (c *Client) EpisodeVideos(ctx context.Context, tvID int64, season, episode int, lang string) ([]Video, error)
EpisodeVideos fetches /tv/{id}/season/{n}/episode/{e}/videos.
func (*Client) FindByExternalID ¶
FindByExternalID looks up by imdb ("tt...") or tvdb id. source accepts "imdb", "imdb_id", "tvdb", "tvdb_id".
func (*Client) GetJSON ¶
GetJSON performs a rate-limited, cached GET of any TMDB v3 path (for example "/search/keyword") and decodes the JSON body into out. It lets callers reach endpoints this package has no typed helper for.
func (*Client) ImageURL ¶
ImageURL builds a full image URL. Implements core.ImageURLFunc when used as method value.
func (*Client) ImageURLFunc ¶
func (c *Client) ImageURLFunc() core.ImageURLFunc
ImageURLFunc returns c.ImageURL as a core.ImageURLFunc.
func (*Client) Localized ¶
func (c *Client) Localized(ctx context.Context, t *core.Title, language string) (*core.Title, error)
Localized changes presentation only: certification, adult flag and identity remain the canonical catalogue's responsibility, never translated API fields.
func (*Client) MovieDetails ¶
MovieDetails fetches full movie details.
func (*Client) MovieDetailsFresh ¶ added in v0.2.37
MovieDetailsFresh and TVDetailsFresh bypass the response cache for callers that must verify current release dates. They never serve a stale response.
func (*Client) MovieRecommendations ¶
func (*Client) MovieReleaseDates ¶ added in v0.3.0
MovieReleaseDates fetches only a movie's release dates and certifications (the catalogue's rating re-selection; far lighter than MovieDetails).
func (*Client) MovieSimilar ¶
Similar / recommendations helpers.
func (*Client) MovieVideos ¶
MovieVideos fetches /movie/{id}/videos. lang overrides the client language for the include_video_language fallback list.
func (*Client) PersonCombinedCredits ¶ added in v0.2.7
func (c *Client) PersonCombinedCredits(ctx context.Context, id int64) (*PersonCombinedCredits, error)
PersonCombinedCredits fetches /person/{id}/combined_credits.
func (*Client) PersonDetails ¶
PersonDetails fetches /person/{id}.
func (*Client) SearchMovies ¶
SearchMovies / SearchTV / SearchMulti.
func (*Client) SearchMulti ¶
func (*Client) SeasonDetails ¶
SeasonDetails fetches one season with its episodes.
func (*Client) SeasonVideos ¶
func (c *Client) SeasonVideos(ctx context.Context, tvID int64, season int, lang string) ([]Video, error)
SeasonVideos fetches /tv/{id}/season/{n}/videos.
func (*Client) SetConfiguration ¶
func (c *Client) SetConfiguration(cfg *Configuration)
SetConfiguration seeds the image configuration (tests / prefetch).
func (*Client) SetRateShare ¶
SetRateShare divides the configured request rate and burst by nodes, the number of live cluster nodes sharing the API key, with a floor of MinClusterRate requests per second (and burst) so a node of a large cluster still makes progress; nodes ≤ 1 restores the configured rate. TMDB's limit is per key (or per IP), so N nodes at the full rate would together exceed it.
func (*Client) TVContentRatings ¶ added in v0.3.0
TVContentRatings fetches only a show's per-country content ratings.
func (*Client) TVDetailsFresh ¶ added in v0.2.37
func (*Client) TVRecommendations ¶
func (*Client) TrendingAll ¶
func (*Client) TrendingMovies ¶
func (c *Client) TrendingMovies(ctx context.Context, window string, page int) (*Paged[Movie], error)
Trending fetches /trending/{movie|tv|all}/{day|week}. For "all" results are MultiResult.
func (*Client) TrendingTV ¶
func (*Client) UpdateConfig ¶
UpdateConfig changes credentials and locale without replacing the client held by catalogue workers. Existing requests finish with their original snapshot; they cannot populate the new configuration's cache.
type CollectionDetails ¶
type CollectionDetails struct {
ID int64 `json:"id"`
Name string `json:"name"`
Overview string `json:"overview"`
PosterPath string `json:"poster_path"`
BackdropPath string `json:"backdrop_path"`
Parts []Movie `json:"parts"`
}
CollectionDetails is /collection/{id}.
type CollectionRef ¶
type Configuration ¶
type Configuration struct {
Images struct {
BaseURL string `json:"base_url"`
SecureBaseURL string `json:"secure_base_url"`
BackdropSizes []string `json:"backdrop_sizes"`
LogoSizes []string `json:"logo_sizes"`
PosterSizes []string `json:"poster_sizes"`
ProfileSizes []string `json:"profile_sizes"`
StillSizes []string `json:"still_sizes"`
} `json:"images"`
ChangeKeys []string `json:"change_keys"`
}
type ContentRatings ¶
type Credits ¶
type Credits struct {
Cast []CastMember `json:"cast"`
Crew []CastMember `json:"crew"`
}
type DiscoverParams ¶
type DiscoverParams struct {
Page int
SortBy string // e.g. popularity.desc, vote_count.desc, primary_release_date.desc
VoteCountGTE int
VoteAverageGTE float64
WithGenres string // comma/pipe list of genre ids
Year int // primary_release_year (movie) / first_air_date_year (tv)
ReleaseDateGTE string // YYYY-MM-DD
ReleaseDateLTE string
FirstAirGTE string
FirstAirLTE string
IncludeAdult bool
WithOriginalLanguage string
Region string
Extra url.Values // merged last
}
DiscoverParams controls discover queries. Zero values are omitted.
type Episode ¶
type Episode struct {
ID int64 `json:"id"`
Name string `json:"name"`
Overview string `json:"overview"`
EpisodeNumber int `json:"episode_number"`
SeasonNumber int `json:"season_number"`
AirDate string `json:"air_date"`
Runtime *int `json:"runtime"`
StillPath string `json:"still_path"`
VoteAverage float64 `json:"vote_average"`
VoteCount int `json:"vote_count"`
ShowID int64 `json:"show_id"`
Crew []CastMember `json:"crew"`
GuestStars []CastMember `json:"guest_stars"`
}
Episode is a TV episode.
type EpisodeGroup ¶
type EpisodeGroup struct {
EpisodeGroupSummary
Groups []EpisodeSubgroup `json:"groups"`
}
type EpisodeGroupSummary ¶
type EpisodeGroupSummary struct {
ID string `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
Type int `json:"type"`
EpisodeCount int `json:"episode_count"`
GroupCount int `json:"group_count"`
}
EpisodeGroupSummary describes a TMDB alternate order (type 1 original air, 2 absolute, 3 DVD, 4 digital, 5 story arc, 6 production, 7 TV).
type EpisodeSubgroup ¶
type EpisodeSubgroup struct {
ID string `json:"id"`
Name string `json:"name"`
Order int `json:"order"`
Episodes []OrderedEpisode `json:"episodes"`
}
type ExternalIDs ¶
type FindResult ¶
type FindResult struct {
MovieResults []Movie `json:"movie_results"`
TVResults []TVShow `json:"tv_results"`
TVEpisodeResults []Episode `json:"tv_episode_results"`
TVSeasonResults []SeasonSummary `json:"tv_season_results"`
PersonResults []Person `json:"person_results"`
}
FindResult is /find/{id}.
type Movie ¶
type Movie struct {
ID int64 `json:"id"`
Title string `json:"title"`
OriginalTitle string `json:"original_title"`
Overview string `json:"overview"`
PosterPath string `json:"poster_path"`
BackdropPath string `json:"backdrop_path"`
ReleaseDate string `json:"release_date"`
GenreIDs []int `json:"genre_ids"`
Genres []Genre `json:"genres"`
OriginalLanguage string `json:"original_language"`
Popularity float64 `json:"popularity"`
VoteAverage float64 `json:"vote_average"`
VoteCount int `json:"vote_count"`
Adult bool `json:"adult"`
MediaType string `json:"media_type"`
}
Movie is a list/search/discover movie item.
type MovieDetails ¶
type MovieDetails struct {
Movie
Tagline string `json:"tagline"`
Runtime int `json:"runtime"`
Status string `json:"status"`
IMDBID string `json:"imdb_id"`
Budget int64 `json:"budget"`
Revenue int64 `json:"revenue"`
Homepage string `json:"homepage"`
BelongsTo *CollectionRef `json:"belongs_to_collection"`
ProductionCompany []Company `json:"production_companies"`
ProductionCountry []Country `json:"production_countries"`
SpokenLanguages []Language `json:"spoken_languages"`
Credits *Credits `json:"credits"`
ReleaseDates *ReleaseDates `json:"release_dates"`
ExternalIDs *ExternalIDs `json:"external_ids"`
Images *Images `json:"images"`
Keywords *Keywords `json:"keywords"`
AlternativeTitles *AltTitles `json:"alternative_titles"`
Similar *Paged[Movie] `json:"similar"`
Recommendations *Paged[Movie] `json:"recommendations"`
}
MovieDetails is /movie/{id} with append_to_response.
type MultiResult ¶
type MultiResult struct {
ID int64 `json:"id"`
MediaType string `json:"media_type"`
Title string `json:"title"`
Name string `json:"name"`
OriginalTitle string `json:"original_title"`
OriginalName string `json:"original_name"`
Overview string `json:"overview"`
PosterPath string `json:"poster_path"`
BackdropPath string `json:"backdrop_path"`
ProfilePath string `json:"profile_path"`
ReleaseDate string `json:"release_date"`
FirstAirDate string `json:"first_air_date"`
GenreIDs []int `json:"genre_ids"`
OriginalLanguage string `json:"original_language"`
Popularity float64 `json:"popularity"`
VoteAverage float64 `json:"vote_average"`
VoteCount int `json:"vote_count"`
}
MultiResult is one /search/multi item (movie, tv or person fields unioned).
func (MultiResult) AsMovie ¶
func (m MultiResult) AsMovie() Movie
func (MultiResult) AsTV ¶
func (m MultiResult) AsTV() TVShow
type Option ¶
type Option func(*options)
Option customises a Client.
func WithBaseURL ¶
func WithCacheTTL ¶
func WithHTTPClient ¶
func WithMaxRetries ¶
func WithRateLimit ¶
func WithUserAgent ¶
type OrderedEpisode ¶
type Paged ¶
type Paged[T any] struct { Page int `json:"page"` Results []T `json:"results"` TotalPages int `json:"total_pages"` TotalResults int `json:"total_results"` }
Paged is a TMDB paged list response.
type Person ¶
type Person struct {
ID int64 `json:"id"`
Name string `json:"name"`
Biography string `json:"biography"`
Birthday string `json:"birthday"`
Deathday string `json:"deathday"`
PlaceOfBirth string `json:"place_of_birth"`
ProfilePath string `json:"profile_path"`
KnownForDepartment string `json:"known_for_department"`
Popularity float64 `json:"popularity"`
IMDBID string `json:"imdb_id"`
}
type PersonCombinedCredits ¶ added in v0.2.7
type PersonCombinedCredits struct {
ID int64 `json:"id"`
Cast []PersonCredit `json:"cast"`
Crew []PersonCredit `json:"crew"`
}
PersonCombinedCredits is /person/{id}/combined_credits.
type PersonCredit ¶ added in v0.2.7
type PersonCredit struct {
MultiResult
Character string `json:"character"`
Job string `json:"job"`
Department string `json:"department"`
EpisodeCount int `json:"episode_count"`
}
PersonCredit is one work in /person/{id}/combined_credits.
type ReleaseDateEntry ¶
type ReleaseDates ¶
type ReleaseDates struct {
Results []struct {
ISO3166 string `json:"iso_3166_1"`
ReleaseDate []ReleaseDateEntry `json:"release_dates"`
} `json:"results"`
}
type SeasonDetails ¶
type SeasonDetails struct {
ID int64 `json:"id"`
Name string `json:"name"`
Overview string `json:"overview"`
SeasonNumber int `json:"season_number"`
AirDate string `json:"air_date"`
PosterPath string `json:"poster_path"`
Episodes []Episode `json:"episodes"`
VoteAverage float64 `json:"vote_average"`
}
SeasonDetails is /tv/{id}/season/{n}.
type SeasonSummary ¶
type SeasonSummary struct {
ID int64 `json:"id"`
Name string `json:"name"`
Overview string `json:"overview"`
SeasonNumber int `json:"season_number"`
EpisodeCount int `json:"episode_count"`
AirDate string `json:"air_date"`
PosterPath string `json:"poster_path"`
VoteAverage float64 `json:"vote_average"`
}
type TVDetails ¶
type TVDetails struct {
TVShow
Tagline string `json:"tagline"`
Status string `json:"status"`
Type string `json:"type"`
EpisodeRunTime []int `json:"episode_run_time"`
NumberOfSeasons int `json:"number_of_seasons"`
NumberOfEpisodes int `json:"number_of_episodes"`
LastAirDate string `json:"last_air_date"`
LastEpisodeToAir *Episode `json:"last_episode_to_air"`
InProduction bool `json:"in_production"`
Homepage string `json:"homepage"`
Seasons []SeasonSummary `json:"seasons"`
Networks []Network `json:"networks"`
ProductionCompany []Company `json:"production_companies"`
ProductionCountry []Country `json:"production_countries"`
CreatedBy []struct {
ID int64 `json:"id"`
Name string `json:"name"`
ProfilePath string `json:"profile_path"`
} `json:"created_by"`
Credits *Credits `json:"credits"`
AggregateCredits *Credits `json:"aggregate_credits"`
ContentRatings *ContentRatings `json:"content_ratings"`
ExternalIDs *ExternalIDs `json:"external_ids"`
Images *Images `json:"images"`
Keywords *Keywords `json:"keywords"`
AlternativeTitles *AltTitles `json:"alternative_titles"`
Similar *Paged[TVShow] `json:"similar"`
Recommendations *Paged[TVShow] `json:"recommendations"`
}
TVDetails is /tv/{id} with append_to_response.
type TVShow ¶
type TVShow struct {
ID int64 `json:"id"`
Name string `json:"name"`
OriginalName string `json:"original_name"`
Overview string `json:"overview"`
PosterPath string `json:"poster_path"`
BackdropPath string `json:"backdrop_path"`
FirstAirDate string `json:"first_air_date"`
GenreIDs []int `json:"genre_ids"`
Genres []Genre `json:"genres"`
OriginCountry []string `json:"origin_country"`
OriginalLanguage string `json:"original_language"`
Popularity float64 `json:"popularity"`
VoteAverage float64 `json:"vote_average"`
VoteCount int `json:"vote_count"`
Adult bool `json:"adult"`
MediaType string `json:"media_type"`
}
TVShow is a list/search/discover TV item.
type Video ¶
type Video struct {
ID string `json:"id"`
ISO639 string `json:"iso_639_1"`
ISO3166 string `json:"iso_3166_1"`
Key string `json:"key"`
Name string `json:"name"`
Site string `json:"site"`
Size int `json:"size"` // vertical resolution, e.g. 1080
Type string `json:"type"` // Trailer, Teaser, Clip, Featurette, ...
Official bool `json:"official"`
PublishedAt string `json:"published_at"`
}
Video is one TMDB /videos result: a trailer, teaser or other clip hosted on an external site (usually YouTube or Vimeo). Key is the site-specific video id, not a playable URL.