225 lines
5.5 KiB
Go
225 lines
5.5 KiB
Go
// Package gomdb is a golang implementation of the OMDB API.
|
|
package gomdb
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"net/http"
|
|
"net/url"
|
|
)
|
|
|
|
const (
|
|
baseURL = "https://www.omdbapi.com"
|
|
plot = "full"
|
|
tomatoes = "true"
|
|
|
|
MovieSearch = "movie"
|
|
SeriesSearch = "series"
|
|
EpisodeSearch = "episode"
|
|
)
|
|
|
|
type OmdbApi struct {
|
|
apiKey string
|
|
}
|
|
|
|
func Init(apiKey string) *OmdbApi {
|
|
return &OmdbApi{apiKey: apiKey}
|
|
}
|
|
|
|
// QueryData is the type to create the search query
|
|
type QueryData struct {
|
|
Title string
|
|
Year string
|
|
ImdbId string
|
|
SearchType string
|
|
Season string
|
|
Episode string
|
|
}
|
|
|
|
// SearchResult is the type for the search results
|
|
type SearchResult struct {
|
|
Title string
|
|
Year string
|
|
ImdbID string
|
|
Type string
|
|
}
|
|
|
|
// SearchResponse is the struct of the response in a search
|
|
type SearchResponse struct {
|
|
Search []SearchResult
|
|
Response string
|
|
Error string
|
|
totalResults int
|
|
}
|
|
|
|
// Ratings is a combination of all ratings
|
|
type Ratings struct {
|
|
Source string
|
|
Value string
|
|
}
|
|
|
|
// MovieResult is the result struct of an specific movie search
|
|
type MovieResult struct {
|
|
Title string `json:"Title"`
|
|
Year string `json:"Year"`
|
|
Rated string `json:"Rated"`
|
|
Released string `json:"Released"`
|
|
Runtime string `json:"Runtime"`
|
|
Genre string `json:"Genre"`
|
|
Director string `json:"Director"`
|
|
Writer string `json:"Writer"`
|
|
Actors string `json:"Actors"`
|
|
Plot string `json:"Plot"`
|
|
Language string `json:"Language"`
|
|
Country string `json:"Country"`
|
|
Awards string `json:"Awards"`
|
|
Poster string `json:"Poster"`
|
|
Ratings []Ratings `json:"Ratings"`
|
|
Metascore string `json:"Metascore"`
|
|
ImdbRating string `json:"imdbRating"`
|
|
ImdbVotes string `json:"imdbVotes"`
|
|
ImdbID string `json:"imdbID"`
|
|
Type string `json:"Type"`
|
|
DVD string `json:"DVD"`
|
|
BoxOffice string `json:"BoxOffice"`
|
|
Production string `json:"Production"`
|
|
Website string `json:"Website"`
|
|
Response string `json:"Response"`
|
|
Error string `json:"Error"`
|
|
}
|
|
|
|
// Search for movies given a Title and year, Year is optional you can pass nil
|
|
func (api *OmdbApi) Search(query *QueryData) (*SearchResponse, error) {
|
|
resp, err := api.requestAPI("search", query.Title, query.Year, query.SearchType)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
r := new(SearchResponse)
|
|
err = json.NewDecoder(resp.Body).Decode(r)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if r.Response == "False" {
|
|
return r, errors.New(r.Error)
|
|
}
|
|
|
|
return r, nil
|
|
}
|
|
|
|
// MovieByTitle returns a MovieResult given Title
|
|
func (api *OmdbApi) MovieByTitle(query *QueryData) (*MovieResult, error) {
|
|
resp, err := api.requestAPI("title", query.Title, query.Year, query.SearchType, query.Season,
|
|
query.Episode)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
r := new(MovieResult)
|
|
err = json.NewDecoder(resp.Body).Decode(r)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if r.Response == "False" {
|
|
return r, errors.New(r.Error)
|
|
}
|
|
return r, nil
|
|
}
|
|
|
|
// MovieByImdbID returns a MovieResult given a ImdbID ex:"tt2015381"
|
|
func (api *OmdbApi) MovieByImdbID(query *QueryData) (*MovieResult, error) {
|
|
|
|
resp, err := api.requestAPI("id", query.ImdbId, query.Year, query.SearchType, query.Season, query.Episode)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
r := new(MovieResult)
|
|
err = json.NewDecoder(resp.Body).Decode(r)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if r.Response == "False" {
|
|
return r, errors.New(r.Error)
|
|
}
|
|
return r, nil
|
|
}
|
|
|
|
// helper function to call the API
|
|
// param: apiCategory refers to which API we are calling. Can be "search", "title" or "id"
|
|
// Depending on that value, we will search by "t" or "s" or "i"
|
|
// param: params are the variadic list of params passed for that category
|
|
func (api *OmdbApi) requestAPI(apiCategory string, params ...string) (resp *http.Response, err error) {
|
|
var URL *url.URL
|
|
URL, err = url.Parse(baseURL)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Checking for invalid category
|
|
if len(params) > 1 && params[2] != "" {
|
|
if params[2] != MovieSearch &&
|
|
params[2] != SeriesSearch &&
|
|
params[2] != EpisodeSearch {
|
|
return nil, errors.New("Invalid search category- " + params[2])
|
|
}
|
|
}
|
|
URL.Path += "/"
|
|
parameters := url.Values{}
|
|
parameters.Add("apikey", api.apiKey)
|
|
|
|
switch apiCategory {
|
|
case "search":
|
|
parameters.Add("s", params[0])
|
|
parameters.Add("y", params[1])
|
|
parameters.Add("type", params[2])
|
|
case "title":
|
|
parameters.Add("t", params[0])
|
|
parameters.Add("y", params[1])
|
|
parameters.Add("type", params[2])
|
|
parameters.Add("Season", params[3])
|
|
parameters.Add("Episode", params[4])
|
|
parameters.Add("plot", plot)
|
|
parameters.Add("tomatoes", tomatoes)
|
|
case "id":
|
|
parameters.Add("i", params[0])
|
|
parameters.Add("type", params[2])
|
|
parameters.Add("Season", params[3])
|
|
parameters.Add("Episode", params[4])
|
|
parameters.Add("plot", plot)
|
|
parameters.Add("tomatoes", tomatoes)
|
|
}
|
|
|
|
URL.RawQuery = parameters.Encode()
|
|
res, err := http.Get(URL.String())
|
|
err = checkErr(res.StatusCode)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return res, nil
|
|
}
|
|
|
|
func checkErr(status int) error {
|
|
if status != 200 {
|
|
return fmt.Errorf("Status Code %d received from OMDb", status)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Stringer Interface for MovieResult
|
|
func (mr MovieResult) String() string {
|
|
return fmt.Sprintf("#%s: %s (%s)", mr.ImdbID, mr.Title, mr.Year)
|
|
}
|
|
|
|
// Stringer Interface for SearchResult
|
|
func (sr SearchResult) String() string {
|
|
return fmt.Sprintf("#%s: %s (%s) Type: %s", sr.ImdbID, sr.Title, sr.Year, sr.Type)
|
|
}
|