opensubtitles

package module
v0.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 15, 2025 License: MIT Imports: 10 Imported by: 0

README

opensubtitles-go

A Go client library for interacting with the OpenSubtitles REST API and XML-RPC Upload API.

Go Reference

Features

  • Access to OpenSubtitles REST API endpoints:
    • Authentication (Login, Logout)
    • Subtitle Search
    • Subtitle Download Link Retrieval
    • Discover (Latest, Popular, Featured)
    • Utilities (Formats, Languages, User Info)
  • XML-RPC based Subtitle Upload functionality.
  • Type-safe request parameters and response structs.
  • Built-in helpers for common tasks (e.g., hashing - provided by upload package).

Installation

go get github.com/angelospk/opensubtitles-go

(Remember to run go mod tidy in your project)

Requirements

  • Go: Version 1.18 or higher.
  • OpenSubtitles API Key: Obtainable from the OpenSubtitles website.
  • OpenSubtitles Account: Required for Login, Download, and Upload operations.

Usage

Client Initialization
package main

import (
	"fmt"
	opensubtitles "github.com/angelospk/opensubtitles-go"
)

func main() {
	config := opensubtitles.Config{
		ApiKey:    "YOUR_API_KEY", // Replace with your actual API key
		UserAgent: "YourAppName/1.0", // Replace with your app's user agent. If there are errors regarding userAgent, leave it as an empty string ""
	}

	client, err := opensubtitles.NewClient(config)
	if err != nil {
		fmt.Printf("Error creating client: %v\n", err)
		return
	}
	fmt.Println("Client initialized successfully!")

	// ... use client methods ...
}
Authentication (Login/Logout)
	// Login (Requires username and password)
	loginParams := opensubtitles.LoginRequest{
		Username: "YOUR_USERNAME",
		Password: "YOUR_PASSWORD",
	}
	loginResp, err := client.Login(context.Background(), loginParams)
	if err != nil {
		// Handle error
	}
	fmt.Printf("Logged in! Token starts with: %s\n", loginResp.Token[:5])

	// ... perform authenticated actions (download, get user info, etc.) ...

	// Logout
	err = client.Logout(context.Background())
	if err != nil {
		// Handle error
	}
	fmt.Println("Logged out.")
Searching Subtitles
	// Search by IMDb ID
	var imdbID = 1375666 // Example: Inception
	searchParams := opensubtitles.SearchSubtitlesParams{
		IMDbID: &imdbID,
		Languages: opensubtitles.String("en"), // Optional: filter by language
	}

	searchResp, err := client.SearchSubtitles(context.Background(), searchParams)
	if err != nil {
		// Handle error
	}

	fmt.Printf("Found %d subtitles.\n", searchResp.TotalCount)
	for _, sub := range searchResp.Data {
		fmt.Printf("- Subtitle ID: %s, Lang: %s, File ID: %d\n",
			sub.ID, sub.Attributes.Language, sub.Attributes.Files[0].FileID)
	}

(See examples/search/main.go for more search options like movie hash or query string.)

	// Requires prior login
	var fileID = 1234567 // Replace with a valid File ID from search results
	downloadPayload := opensubtitles.DownloadRequest{
		FileID: fileID,
	}
	downloadResp, err := client.Download(context.Background(), downloadPayload)
	if err != nil {
		// Handle error (e.g., quota exceeded - check for specific error types)
	}

	fmt.Printf("Download Link: %s\n", downloadResp.Link)
	fmt.Printf("Remaining downloads: %d\n", downloadResp.Remaining)
	// IMPORTANT: Use an HTTP client to fetch the subtitle content from downloadResp.Link

(See examples/download/main.go for a runnable example.)

Uploading Subtitles (XML-RPC)

Uploading uses the separate XML-RPC endpoint and requires its own login flow using an MD5 hash of the password.

  1. Create an Uploader instance:

    import "github.com/angelospk/opensubtitles-go/upload"
    
    uploader, err := upload.NewXmlRpcUploader()
    if err != nil {
        // Handle error
    }
    defer uploader.Close()
    
  2. Login via Uploader:

    import (
        "crypto/md5"
        "encoding/hex"
    )
    
    username := "YOUR_USERNAME"
    password := "YOUR_PASSWORD"
    userAgent := "YourAppName/1.0"
    
    hasher := md5.New()
    hasher.Write([]byte(password))
    md5Password := hex.EncodeToString(hasher.Sum(nil))
    
    // Login using the uploader instance
    err = uploader.Login(username, md5Password, "en", userAgent)
    if err != nil {
        // Handle XML-RPC login error
    }
    
  3. Prepare Upload Intent and Upload:

    import "path/filepath"
    
    intent := upload.UserUploadIntent{
        SubtitleFilePath: "/path/to/your/subtitle.srt",
        SubtitleFileName: filepath.Base("/path/to/your/subtitle.srt"),
        IMDBID:           "1371111", // Example: Inception
        LanguageID:       "en",
        // Optionally provide VideoFilePath for movie hash calculation
        // VideoFilePath:    "/path/to/movie.mkv",
        // VideoFileName:    filepath.Base("/path/to/movie.mkv"),
    }
    
    subtitleURL, err := uploader.Upload(intent)
    if err != nil {
        // Handle upload error (e.g., upload.ErrUploadDuplicate)
    }
    
    fmt.Printf("Subtitle uploaded successfully! URL: %s\n", subtitleURL)
    
  4. Logout via Uploader:

    err = uploader.Logout()
    if err != nil {
        // Handle logout error
    }
    

(See examples/upload/main.go for a complete, runnable upload example.)

Examples

Runnable examples can be found in the examples/ directory:

  • examples/search/: Demonstrates searching for subtitles.
  • examples/download/: Demonstrates logging in and requesting a download link.
  • examples/upload/: Demonstrates the full XML-RPC upload flow.

To run an example (e.g., search):

cd examples/search
go mod init example.com/search # Run only once per example directory
go mod tidy
go run main.go

Contributing

Contributions are welcome! Please feel free to submit pull requests or open issues.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ApiDataWrapper

type ApiDataWrapper struct {
	ID   string `json:"id"`
	Type string `json:"type"` // e.g., "subtitle", "feature"
}

ApiDataWrapper wraps the common "id", "type", "attributes" structure. We'll often embed this or use specific types due to Go's static nature.

type BaseUserInfo

type BaseUserInfo struct {
	AllowedDownloads int    `json:"allowed_downloads"`
	Level            string `json:"level"`
	UserID           int    `json:"user_id"`
	ExtInstalled     bool   `json:"ext_installed"`
	VIP              bool   `json:"vip"`
}

BaseUserInfo contains common user details.

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client is the main OpenSubtitles API client.

func NewClient

func NewClient(config Config) (*Client, error)

NewClient creates a new OpenSubtitles API client.

func (*Client) DiscoverLatest

func (c *Client) DiscoverLatest(ctx context.Context, params DiscoverParams) (*DiscoverLatestResponse, error)

DiscoverLatest retrieves the latest added subtitles.

func (*Client) DiscoverMostDownloaded

func (c *Client) DiscoverMostDownloaded(ctx context.Context, params DiscoverParams) (*DiscoverMostDownloadedResponse, error)

DiscoverMostDownloaded retrieves the most downloaded subtitles.

func (*Client) DiscoverPopular

func (c *Client) DiscoverPopular(ctx context.Context, params DiscoverParams) (*DiscoverPopularResponse, error)

DiscoverPopular retrieves popular features (movies/tvshows).

func (*Client) Download

func (c *Client) Download(ctx context.Context, params DownloadRequest) (*DownloadResponse, error)

Download requests a download link for a specific subtitle file. Requires authentication.

func (*Client) GetCurrentBaseURL

func (c *Client) GetCurrentBaseURL() string

GetCurrentBaseURL returns the base URL currently used by the client.

func (*Client) GetCurrentToken

func (c *Client) GetCurrentToken() *string

GetCurrentToken returns the currently stored auth token.

func (*Client) GetUserInfo

func (c *Client) GetUserInfo(ctx context.Context) (*GetUserInfoResponse, error)

GetUserInfo retrieves information about the currently authenticated user. Requires authentication (a valid token must be set in the client).

func (*Client) Guessit

func (c *Client) Guessit(ctx context.Context, params GuessitParams) (*GuessitResponse, error)

Guessit attempts to parse structured information (title, year, season, etc.) from a filename using the OpenSubtitles guessit utility.

func (*Client) Login

func (c *Client) Login(ctx context.Context, params LoginRequest) (*LoginResponse, error)

Login authenticates the user with username and password, retrieving an API token. The token and the appropriate base URL (e.g., vip-api.opensubtitles.com) are stored internally in the client for subsequent requests.

func (*Client) Logout

func (c *Client) Logout(ctx context.Context) (*LogoutResponse, error)

Logout invalidates the current API token. It clears the token stored internally in the client.

func (*Client) SearchFeatures

func (c *Client) SearchFeatures(ctx context.Context, params SearchFeaturesParams) (*SearchFeaturesResponse, error)

SearchFeatures searches for features (movies, tvshows, episodes) based on criteria. Note: The response contains a slice of Feature structs where the Attributes field is an interface{}. Users will need to inspect the FeatureType within the attributes (after potentially unmarshalling the interface{} into a map[string]interface{}) and then perform a type assertion or unmarshal the attributes into the specific type (FeatureMovieAttributes, FeatureTvshowAttributes, FeatureEpisodeAttributes) to access type-specific fields.

func (*Client) SearchSubtitles

func (c *Client) SearchSubtitles(ctx context.Context, params SearchSubtitlesParams) (*SearchSubtitlesResponse, error)

SearchSubtitles searches for subtitles based on various criteria.

func (*Client) SetAuthToken

func (c *Client) SetAuthToken(token string, baseUrl string) error

SetAuthToken allows manually setting the auth token (e.g., loading from storage).

func (*Client) Uploader

func (c *Client) Uploader() upload.Uploader

Uploader returns the configured uploader instance for XML-RPC operations.

type Config

type Config struct {
	ApiKey    string
	UserAgent string
	BaseURL   string // Optional: Override default base URL
}

Config holds the configuration for the OpenSubtitles client.

type DiscoverLatestResponse

type DiscoverLatestResponse struct {
	TotalPages int        `json:"total_pages"` // Should be 1
	TotalCount int        `json:"total_count"` // Should be 60
	Page       int        `json:"page"`        // Should be 1
	Data       []Subtitle `json:"data"`
}

DiscoverLatestResponse wraps the list of latest subtitles (fixed count).

type DiscoverMostDownloadedResponse

type DiscoverMostDownloadedResponse struct {
	PaginatedResponse
	Data []Subtitle `json:"data"`
}

DiscoverMostDownloadedResponse wraps paginated most downloaded subtitles.

type DiscoverParams

type DiscoverParams struct {
	Language *LanguageCode `url:"language,omitempty"` // Single language code or "all"
	Type     *FeatureType  `url:"type,omitempty"`     // "movie", "tvshow"
}

DiscoverParams defines common query parameters for discover endpoints.

type DiscoverPopularResponse

type DiscoverPopularResponse struct {
	Data []Feature `json:"data"` // Contains FeatureMovieAttributes or FeatureTvshowAttributes
}

DiscoverPopularResponse wraps the list of popular features. Note: API returns mixed movie/tvshow features. Need runtime check.

type DownloadRequest

type DownloadRequest struct {
	FileID        int      `json:"file_id"`
	SubFormat     *string  `json:"sub_format,omitempty"`
	FileName      *string  `json:"file_name,omitempty"`
	InFPS         *float64 `json:"in_fps,omitempty"`         // Pointer as optional
	OutFPS        *float64 `json:"out_fps,omitempty"`        // Pointer as optional
	Timeshift     *float64 `json:"timeshift,omitempty"`      // Pointer as optional
	ForceDownload *bool    `json:"force_download,omitempty"` // Pointer as optional
}

DownloadRequest is the request body for the /download endpoint.

type DownloadResponse

type DownloadResponse struct {
	Link         string    `json:"link"`
	FileName     string    `json:"file_name"`
	Requests     int       `json:"requests"`
	Remaining    int       `json:"remaining"`
	Message      string    `json:"message"`
	ResetTime    string    `json:"reset_time"`
	ResetTimeUTC time.Time `json:"reset_time_utc"` // Use time.Time
}

DownloadResponse is the response from the /download endpoint.

type Feature

type Feature struct {
	ApiDataWrapper
	Attributes interface{} `json:"attributes"` // Use specific attribute struct after unmarshalling based on FeatureType
}

Feature represents any feature type returned by the API. Use type assertion on Attributes based on FeatureType.

type FeatureBaseAttributes

type FeatureBaseAttributes struct {
	FeatureID       string         `json:"feature_id"`
	FeatureType     string         `json:"feature_type"` // "Movie", "Tvshow", "Episode"
	Title           string         `json:"title"`
	OriginalTitle   *string        `json:"original_title"` // Pointer as can be null
	Year            string         `json:"year"`           // String in API response
	IMDbID          *int           `json:"imdb_id"`        // Pointer as can be null
	TMDBID          *int           `json:"tmdb_id"`        // Pointer as can be null
	TitleAKA        []string       `json:"title_aka"`
	URL             string         `json:"url"`
	ImgURL          *string        `json:"img_url"` // Pointer as can be null
	SubtitlesCount  int            `json:"subtitles_count"`
	SubtitlesCounts SubtitleCounts `json:"subtitles_counts"`
}

FeatureBaseAttributes holds common fields for all feature types.

type FeatureEpisodeAttributes

type FeatureEpisodeAttributes struct {
	FeatureBaseAttributes
	ParentIMDbID    *int    `json:"parent_imdb_id"`    // Pointer as can be null
	ParentTitle     *string `json:"parent_title"`      // Pointer as can be null
	ParentTMDBID    *int    `json:"parent_tmdb_id"`    // Pointer as can be null
	ParentFeatureID *string `json:"parent_feature_id"` // Pointer as can be null
	SeasonNumber    int     `json:"season_number"`
	EpisodeNumber   int     `json:"episode_number"`
	MovieName       *string `json:"movie_name"` // Optional formatted name
}

FeatureEpisodeAttributes specific fields for episodes.

type FeatureMovieAttributes

type FeatureMovieAttributes struct {
	FeatureBaseAttributes
	// Potentially null fields that might appear from schema examples
	SeasonsCount    *int    `json:"seasons_count"`
	ParentTitle     *string `json:"parent_title"`
	SeasonNumber    *int    `json:"season_number"`
	EpisodeNumber   *int    `json:"episode_number"`
	ParentIMDbID    *int    `json:"parent_imdb_id"`
	ParentTMDBID    *int    `json:"parent_tmdb_id"`    // Added for consistency
	ParentFeatureID *string `json:"parent_feature_id"` // Added for consistency
}

FeatureMovieAttributes specific fields for movies.

type FeatureTvshowAttributes

type FeatureTvshowAttributes struct {
	FeatureBaseAttributes
	SeasonsCount int            `json:"seasons_count"`
	Seasons      []TvshowSeason `json:"seasons"`
}

FeatureTvshowAttributes specific fields for TV shows.

type FeatureType

type FeatureType string

FeatureType defines the type of a feature.

const (
	FeatureMovie   FeatureType = "movie"
	FeatureTVShow  FeatureType = "tvshow"
	FeatureEpisode FeatureType = "episode"
	FeatureAll     FeatureType = "all" // For searching
)

type FilterInclusion

type FilterInclusion string

FilterInclusion defines include/exclude options.

const (
	Include FilterInclusion = "include"
	Exclude FilterInclusion = "exclude"
)

type FilterInclusionOnly

type FilterInclusionOnly string

FilterInclusionOnly defines include/exclude/only options.

const (
	IncludeOnly FilterInclusionOnly = "include"
	ExcludeOnly FilterInclusionOnly = "exclude" // Not used in docs, but for completeness
	Only        FilterInclusionOnly = "only"
)

type FilterTrustedSources

type FilterTrustedSources string

FilterTrustedSources defines include/only options for trusted sources.

const (
	IncludeTrusted FilterTrustedSources = "include"
	OnlyTrusted    FilterTrustedSources = "only"
)

type GetUserInfoResponse

type GetUserInfoResponse struct {
	Data UserInfo `json:"data"`
}

GetUserInfoResponse wraps the UserInfo data.

type GuessitParams

type GuessitParams struct {
	Filename string `url:"filename"` // Required
}

GuessitParams defines query parameters for the /utilities/guessit endpoint.

type GuessitResponse

type GuessitResponse struct {
	Title            *string       `json:"title"`
	Year             *int          `json:"year"`
	Season           *int          `json:"season"`
	Episode          *int          `json:"episode"`
	EpisodeTitle     *string       `json:"episode_title"`
	Language         *LanguageCode `json:"language"`
	SubtitleLanguage *LanguageCode `json:"subtitle_language"`
	ScreenSize       *string       `json:"screen_size"`
	StreamingService *string       `json:"streaming_service"`
	Source           *string       `json:"source"`
	Other            *string       `json:"other"` // Docs example show null, not array
	AudioCodec       *string       `json:"audio_codec"`
	AudioChannels    *string       `json:"audio_channels"`
	AudioProfile     *string       `json:"audio_profile"`
	VideoCodec       *string       `json:"video_codec"`
	ReleaseGroup     *string       `json:"release_group"`
	Type             *string       `json:"type"` // "episode", "movie"
}

GuessitResponse is the response from the /utilities/guessit endpoint. All fields are pointers as they might be null if not detected.

type LanguageCode

type LanguageCode string

LanguageCode represents an ISO 639-1 or 639-2/B language code.

type LoginRequest

type LoginRequest struct {
	Username string `json:"username"`
	Password string `json:"password"`
}

LoginRequest is the request body for the login endpoint.

type LoginResponse

type LoginResponse struct {
	User    LoginUser `json:"user"`
	BaseURL string    `json:"base_url"`
	Token   string    `json:"token"`
	Status  int       `json:"status"`
}

LoginResponse is the response from the login endpoint.

type LoginUser

type LoginUser struct {
	BaseUserInfo
	AllowedTranslations int `json:"allowed_translations"`
}

LoginUser extends BaseUserInfo with fields specific to the login response.

type LogoutResponse

type LogoutResponse struct {
	Message string `json:"message"`
	Status  int    `json:"status"`
}

LogoutResponse is the response from the logout endpoint.

type PaginatedResponse

type PaginatedResponse struct {
	TotalPages int `json:"total_pages"`
	TotalCount int `json:"total_count"`
	PerPage    int `json:"per_page"`
	Page       int `json:"page"`
}

PaginatedResponse defines the structure for paginated API responses.

type RelatedLink struct {
	Label  string  `json:"label"`
	URL    string  `json:"url"`
	ImgURL *string `json:"img_url"` // Pointer as optional
}

RelatedLink represents links found in subtitle details.

type SearchFeaturesParams

type SearchFeaturesParams struct {
	FeatureID  *int    `url:"feature_id,omitempty"`
	IMDbID     *string `url:"imdb_id,omitempty"` // String to handle potential leading zeros if needed, API expects number string
	TMDBID     *string `url:"tmdb_id,omitempty"` // String based on example
	Query      *string `url:"query,omitempty"`
	QueryMatch *string `url:"query_match,omitempty"` // "start", "word", "exact"
	FullSearch *bool   `url:"full_search,omitempty"`
	Type       *string `url:"type,omitempty"` // FeatureType or "all" or empty string
	Year       *int    `url:"year,omitempty"`
}

SearchFeaturesParams defines query parameters for the /features endpoint. Use pointers for optional fields. Use `url:"..."` tag for query string encoding.

type SearchFeaturesResponse

type SearchFeaturesResponse struct {
	Data []Feature `json:"data"`
}

SearchFeaturesResponse wraps the list of features.

type SearchSubtitlesParams

type SearchSubtitlesParams struct {
	ID                *int                  `url:"id,omitempty"` // Feature ID
	IMDbID            *int                  `url:"imdb_id,omitempty"`
	TMDBID            *int                  `url:"tmdb_id,omitempty"`
	ParentIMDbID      *int                  `url:"parent_imdb_id,omitempty"`
	ParentTMDBID      *int                  `url:"parent_tmdb_id,omitempty"`
	ParentFeatureID   *int                  `url:"parent_feature_id,omitempty"`
	Query             *string               `url:"query,omitempty"`
	SeasonNumber      *int                  `url:"season_number,omitempty"`
	EpisodeNumber     *int                  `url:"episode_number,omitempty"`
	Moviehash         *string               `url:"moviehash,omitempty"` // Must match `^[a-f0-9]{16}$`
	Languages         *string               `url:"languages,omitempty"` // Comma-separated, sorted LanguageCodes
	Type              *string               `url:"type,omitempty"`      // "movie", "episode", "all"
	Year              *int                  `url:"year,omitempty"`
	AITranslated      *FilterInclusion      `url:"ai_translated,omitempty"`
	MachineTranslated *FilterInclusion      `url:"machine_translated,omitempty"`
	HearingImpaired   *FilterInclusionOnly  `url:"hearing_impaired,omitempty"`
	ForeignPartsOnly  *FilterInclusionOnly  `url:"foreign_parts_only,omitempty"`
	TrustedSources    *FilterTrustedSources `url:"trusted_sources,omitempty"`
	MoviehashMatch    *string               `url:"moviehash_match,omitempty"` // "include", "only"
	UploaderID        *int                  `url:"uploader_id,omitempty"`
	OrderBy           *string               `url:"order_by,omitempty"` // Field name from allowed list
	OrderDirection    *SortDirection        `url:"order_direction,omitempty"`
	Page              *int                  `url:"page,omitempty"`
}

SearchSubtitlesParams defines query parameters for the /subtitles endpoint.

type SearchSubtitlesResponse

type SearchSubtitlesResponse struct {
	PaginatedResponse
	Data []Subtitle `json:"data"`
}

SearchSubtitlesResponse wraps the paginated subtitle results.

type SortDirection

type SortDirection string

SortDirection defines the sorting order.

const (
	SortAsc  SortDirection = "asc"
	SortDesc SortDirection = "desc"
)

type Subtitle

type Subtitle struct {
	ApiDataWrapper
	Attributes SubtitleAttributes `json:"attributes"`
}

Subtitle represents a full subtitle entry.

type SubtitleAttributes

type SubtitleAttributes struct {
	SubtitleID        string                 `json:"subtitle_id"`
	Language          LanguageCode           `json:"language"`
	DownloadCount     int                    `json:"download_count"`
	NewDownloadCount  int                    `json:"new_download_count"`
	HearingImpaired   bool                   `json:"hearing_impaired"`
	HD                bool                   `json:"hd"`
	FPS               *float64               `json:"fps"` // Pointer as can be 0 or null
	Votes             int                    `json:"votes"`
	Points            *float64               `json:"points"` // Pointer, legacy?
	Ratings           float64                `json:"ratings"`
	FromTrusted       bool                   `json:"from_trusted"`
	ForeignPartsOnly  bool                   `json:"foreign_parts_only"`
	UploadDate        time.Time              `json:"upload_date"` // Use time.Time for ISO 8601
	AITranslated      bool                   `json:"ai_translated"`
	MachineTranslated bool                   `json:"machine_translated"`
	MoviehashMatch    *bool                  `json:"moviehash_match,omitempty"` // Pointer, only present sometimes
	Release           string                 `json:"release"`
	Comments          *string                `json:"comments"`           // Pointer as can be null
	LegacySubtitleID  *int                   `json:"legacy_subtitle_id"` // Pointer as can be null
	NbCD              *int                   `json:"nb_cd"`              // Pointer, from example
	Slug              *string                `json:"slug"`               // Pointer, from example
	Uploader          UploaderInfo           `json:"uploader"`
	FeatureDetails    SubtitleFeatureDetails `json:"feature_details"`
	URL               string                 `json:"url"`
	RelatedLinks      []RelatedLink          `json:"related_links"`
	Files             []SubtitleFile         `json:"files"`
}

SubtitleAttributes holds the details of a subtitle entry.

type SubtitleCounts

type SubtitleCounts map[LanguageCode]int

SubtitleCounts maps language codes to subtitle counts.

type SubtitleFeatureDetails

type SubtitleFeatureDetails struct {
	FeatureID       int     `json:"feature_id"`
	FeatureType     string  `json:"feature_type"` // "Movie", "Episode"
	Year            int     `json:"year"`
	Title           string  `json:"title"`
	MovieName       string  `json:"movie_name"`
	IMDbID          *int    `json:"imdb_id"`
	TMDBID          *int    `json:"tmdb_id"`
	SeasonNumber    *int    `json:"season_number"`
	EpisodeNumber   *int    `json:"episode_number"`
	ParentIMDbID    *int    `json:"parent_imdb_id"`
	ParentTMDBID    *int    `json:"parent_tmdb_id"`
	ParentTitle     *string `json:"parent_title"`
	ParentFeatureID *int    `json:"parent_feature_id"` // Number in example
}

SubtitleFeatureDetails represents the nested feature info within a subtitle.

type SubtitleFile

type SubtitleFile struct {
	FileID   int    `json:"file_id"` // **ID needed for download**
	CDNumber int    `json:"cd_number"`
	FileName string `json:"file_name"`
}

SubtitleFile represents a single file within a subtitle entry.

type TvshowEpisodeStub

type TvshowEpisodeStub struct {
	EpisodeNumber int    `json:"episode_number"`
	Title         string `json:"title"`
	FeatureID     string `json:"feature_id"`
}

TvshowEpisodeStub represents basic episode info within a season list.

type TvshowSeason

type TvshowSeason struct {
	SeasonNumber int                 `json:"season_number"`
	Episodes     []TvshowEpisodeStub `json:"episodes"`
}

TvshowSeason represents a season with its episodes.

type UploaderInfo

type UploaderInfo struct {
	UploaderID *int    `json:"uploader_id"` // Pointer as can be null
	Name       *string `json:"name"`        // Pointer as can be null/empty
	Rank       *string `json:"rank"`        // Pointer as can be null/empty
}

UploaderInfo contains details about the subtitle uploader.

type UserInfo

type UserInfo struct {
	BaseUserInfo
	DownloadsCount     int `json:"downloads_count"`
	RemainingDownloads int `json:"remaining_downloads"`
}

UserInfo contains details from the /infos/user endpoint.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL