go-client/content.go
Deivid Soto f6f24c2c3f
Some checks failed
CI / Test (push) Failing after 1s
CI / Test-1 (push) Failing after 1s
CI / Test-2 (push) Failing after 1s
CI / Lint (push) Failing after 1s
CI / Vet (push) Failing after 1s
feat: implement TorrentClaw Go API client v0.1.0
2026-03-28 11:28:48 +01:00

189 lines
6 KiB
Go

package torrentclaw
import (
"context"
"fmt"
"net/url"
)
// ─── Popular ────
// PopularParams holds the parameters for a popular content request.
type PopularParams struct {
// Limit sets the number of items (1-24, default 12).
Limit int
// Page is the page number (starts at 1).
Page int
// Locale sets the language for localized titles.
Locale string
}
// PopularItem represents a popular content item.
type PopularItem struct {
ID int `json:"id"`
Title string `json:"title"`
Year *int `json:"year,omitempty"`
ContentType string `json:"contentType"`
PosterURL *string `json:"posterUrl,omitempty"`
RatingIMDb *string `json:"ratingImdb,omitempty"`
RatingTMDb *string `json:"ratingTmdb,omitempty"`
Overview *string `json:"overview,omitempty"`
MaxSeeders int `json:"maxSeeders"`
Genres []string `json:"genres,omitempty"`
BestQuality *string `json:"bestQuality,omitempty"`
HasHDR *bool `json:"hasHdr,omitempty"`
TopInfoHash *string `json:"topInfoHash,omitempty"`
}
// PopularResponse is the paginated response from the popular endpoint.
type PopularResponse struct {
Items []PopularItem `json:"items"`
Total int `json:"total"`
Page int `json:"page"`
PageSize int `json:"pageSize"`
}
// ─── Recent ────
// RecentParams holds the parameters for a recent content request.
type RecentParams struct {
// Limit sets the number of items (1-24, default 12).
Limit int
// Page is the page number (starts at 1).
Page int
// Locale sets the language for localized titles.
Locale string
}
// RecentItem represents a recently added content item.
type RecentItem struct {
ID int `json:"id"`
Title string `json:"title"`
Year *int `json:"year,omitempty"`
ContentType string `json:"contentType"`
PosterURL *string `json:"posterUrl,omitempty"`
RatingIMDb *string `json:"ratingImdb,omitempty"`
RatingTMDb *string `json:"ratingTmdb,omitempty"`
Overview *string `json:"overview,omitempty"`
CreatedAt string `json:"createdAt"`
}
// RecentResponse is the paginated response from the recent endpoint.
type RecentResponse struct {
Items []RecentItem `json:"items"`
Total int `json:"total"`
Page int `json:"page"`
PageSize int `json:"pageSize"`
}
// ─── Watch Providers ────
// WatchProviderItem represents a single watch/streaming provider.
type WatchProviderItem struct {
ProviderID int `json:"providerId"`
Name string `json:"name"`
Logo *string `json:"logo,omitempty"`
Link *string `json:"link,omitempty"`
DisplayPriority int `json:"displayPriority,omitempty"`
}
// WatchProviders contains streaming availability grouped by access type.
type WatchProviders struct {
Flatrate []WatchProviderItem `json:"flatrate,omitempty"`
Rent []WatchProviderItem `json:"rent,omitempty"`
Buy []WatchProviderItem `json:"buy,omitempty"`
Free []WatchProviderItem `json:"free,omitempty"`
}
// VPNSuggestion is included when content is available in other countries
// via subscription but not in the user's country.
type VPNSuggestion struct {
AvailableIn []string `json:"availableIn"`
AffiliateURL string `json:"affiliateUrl"`
}
// WatchProvidersResponse contains watch providers for a content item.
type WatchProvidersResponse struct {
ContentID int `json:"contentId"`
Country string `json:"country"`
Providers WatchProviders `json:"providers"`
VPNSuggestion *VPNSuggestion `json:"vpnSuggestion,omitempty"`
Attribution string `json:"attribution"`
}
// ─── Credits ────
// CastMember represents an actor in a movie or TV show.
type CastMember struct {
TmdbID *int `json:"tmdbId,omitempty"`
Name string `json:"name"`
Character string `json:"character"`
ProfileURL *string `json:"profileUrl,omitempty"`
}
// CreditsResponse contains the director and cast for a content item.
type CreditsResponse struct {
ContentID int `json:"contentId"`
Director *string `json:"director,omitempty"`
DirectorTmdbID *int `json:"directorTmdbId,omitempty"`
Cast []CastMember `json:"cast"`
}
// ─── Methods ────
// Popular returns the most popular content ranked by community engagement.
func (c *Client) Popular(ctx context.Context, params PopularParams) (*PopularResponse, error) {
q := url.Values{}
addIntParam(q, "limit", params.Limit)
addIntParam(q, "page", params.Page)
addStringParam(q, "locale", params.Locale)
var resp PopularResponse
if err := c.doJSON(ctx, "/api/v1/popular", q, &resp); err != nil {
return nil, err
}
return &resp, nil
}
// Recent returns the most recently added content.
func (c *Client) Recent(ctx context.Context, params RecentParams) (*RecentResponse, error) {
q := url.Values{}
addIntParam(q, "limit", params.Limit)
addIntParam(q, "page", params.Page)
addStringParam(q, "locale", params.Locale)
var resp RecentResponse
if err := c.doJSON(ctx, "/api/v1/recent", q, &resp); err != nil {
return nil, err
}
return &resp, nil
}
// WatchProviders returns streaming/watch providers for a content item.
// The country parameter is an ISO 3166-1 code (e.g. "US", "ES"). Pass an
// empty string to use the server default ("US").
func (c *Client) WatchProviders(ctx context.Context, contentID int, country string) (*WatchProvidersResponse, error) {
q := url.Values{}
addStringParam(q, "country", country)
path := fmt.Sprintf("/api/v1/content/%d/watch-providers", contentID)
var resp WatchProvidersResponse
if err := c.doJSON(ctx, path, q, &resp); err != nil {
return nil, err
}
return &resp, nil
}
// Credits returns the director and top cast members for a content item.
func (c *Client) Credits(ctx context.Context, contentID int) (*CreditsResponse, error) {
path := fmt.Sprintf("/api/v1/content/%d/credits", contentID)
var resp CreditsResponse
if err := c.doJSON(ctx, path, nil, &resp); err != nil {
return nil, err
}
return &resp, nil
}