go-client/search.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

167 lines
5.4 KiB
Go

package torrentclaw
import (
"context"
"net/url"
)
// SearchParams holds the parameters for a search request.
type SearchParams struct {
// Query is the search query (required, max 200 characters).
Query string
// Type filters by content type: "movie" or "show".
Type string
// Genre filters by genre (exact match), e.g. "Action", "Comedy".
Genre string
// YearMin sets the minimum release year.
YearMin int
// YearMax sets the maximum release year.
YearMax int
// MinRating sets the minimum IMDb/TMDB rating threshold (0-10).
MinRating float64
// Quality filters by video resolution: "480p", "720p", "1080p", "2160p".
Quality string
// Language filters by torrent audio language (ISO 639 code, e.g. "en", "es").
Language string
// Subs filters by subtitle language (ISO 639 code, e.g. "en", "es").
Subs string
// Audio filters by audio codec (substring match, e.g. "aac", "atmos").
Audio string
// HDR filters by HDR format (e.g. "hdr10", "dolby_vision").
HDR string
// Sort sets the sort order: "relevance", "seeders", "year", "rating", "added".
Sort string
// Page is the page number (starts at 1).
Page int
// Limit sets the number of results per page (1-50).
Limit int
// Country is an ISO 3166-1 country code to include streaming availability.
Country string
// Locale sets the language for title/overview translations (e.g. "es", "fr").
Locale string
// Availability filters by torrent availability: "all", "available", "unavailable".
Availability string
// Verified filters to only TrueSpec verified releases.
Verified bool
// Season filters by TV show season number.
Season int
// Episode filters by TV show episode number.
Episode int
}
// SearchResult represents a single content result from a search.
type SearchResult struct {
ID int `json:"id"`
IMDbID *string `json:"imdbId,omitempty"`
TMDbID *int `json:"tmdbId,omitempty"`
ContentType string `json:"contentType"`
Title string `json:"title"`
TitleOriginal *string `json:"titleOriginal,omitempty"`
Year *int `json:"year,omitempty"`
Overview *string `json:"overview,omitempty"`
PosterURL *string `json:"posterUrl,omitempty"`
BackdropURL *string `json:"backdropUrl,omitempty"`
Genres []string `json:"genres,omitempty"`
RatingIMDb *string `json:"ratingImdb,omitempty"`
RatingTMDb *string `json:"ratingTmdb,omitempty"`
ContentURL string `json:"contentUrl"`
HasTorrents bool `json:"hasTorrents"`
Torrents []TorrentInfo `json:"torrents"`
Streaming *StreamingInfo `json:"streaming,omitempty"`
}
// SearchResponse is the paginated response from the search endpoint.
type SearchResponse struct {
Total int `json:"total"`
Page int `json:"page"`
PageSize int `json:"pageSize"`
ParsedSeason *int `json:"parsedSeason,omitempty"`
ParsedEpisode *int `json:"parsedEpisode,omitempty"`
FuzzyMatch *bool `json:"fuzzyMatch,omitempty"`
Results []SearchResult `json:"results"`
}
// AutocompleteParams holds the parameters for an autocomplete request.
type AutocompleteParams struct {
// Query is the search prefix (required, 2-200 characters).
Query string
// Locale sets the language for localized suggestions.
Locale string
}
// AutocompleteSuggestion represents a single autocomplete result.
type AutocompleteSuggestion struct {
ID int `json:"id"`
Title string `json:"title"`
Year *int `json:"year,omitempty"`
ContentType string `json:"contentType"`
PosterURL *string `json:"posterUrl,omitempty"`
MovieCount *int `json:"movieCount,omitempty"`
}
// Search queries the TorrentClaw search endpoint with the given parameters.
// The Query field in params is required.
func (c *Client) Search(ctx context.Context, params SearchParams) (*SearchResponse, error) {
q := url.Values{}
q.Set("q", params.Query)
addStringParam(q, "type", params.Type)
addStringParam(q, "genre", params.Genre)
addIntParam(q, "year_min", params.YearMin)
addIntParam(q, "year_max", params.YearMax)
addFloatParam(q, "min_rating", params.MinRating)
addStringParam(q, "quality", params.Quality)
addStringParam(q, "lang", params.Language)
addStringParam(q, "subs", params.Subs)
addStringParam(q, "audio", params.Audio)
addStringParam(q, "hdr", params.HDR)
addStringParam(q, "sort", params.Sort)
addIntParam(q, "page", params.Page)
addIntParam(q, "limit", params.Limit)
addStringParam(q, "country", params.Country)
addStringParam(q, "locale", params.Locale)
addStringParam(q, "availability", params.Availability)
addBoolParam(q, "verified", params.Verified)
addIntParam(q, "season", params.Season)
addIntParam(q, "episode", params.Episode)
var resp SearchResponse
if err := c.doJSON(ctx, "/api/v1/search", q, &resp); err != nil {
return nil, err
}
return &resp, nil
}
// Autocomplete returns title suggestions for the given query prefix.
func (c *Client) Autocomplete(ctx context.Context, params AutocompleteParams) ([]AutocompleteSuggestion, error) {
q := url.Values{}
q.Set("q", params.Query)
addStringParam(q, "locale", params.Locale)
var resp struct {
Suggestions []AutocompleteSuggestion `json:"suggestions"`
}
if err := c.doJSON(ctx, "/api/v1/autocomplete", q, &resp); err != nil {
return nil, err
}
return resp.Suggestions, nil
}