gomdb/gomdb.go

210 lines
4.8 KiB
Go
Raw Normal View History

2016-06-14 15:06:35 +00:00
// Package gomdb is a golang implementation of the OMDB API.
2015-06-26 20:07:46 +00:00
package gomdb
2014-09-21 17:48:10 +00:00
import (
"encoding/json"
"errors"
"fmt"
"net/http"
"net/url"
2014-09-21 17:48:10 +00:00
)
2016-06-14 15:06:35 +00:00
const (
baseURL = "http://www.omdbapi.com/?"
plot = "full"
tomatoes = "true"
2016-06-14 17:12:01 +00:00
MovieSearch = "movie"
SeriesSearch = "series"
EpisodeSearch = "episode"
2016-06-14 15:06:35 +00:00
)
2014-09-21 17:48:10 +00:00
2016-06-15 06:48:48 +00:00
// QueryData is the type to create the search query
type QueryData struct {
2016-06-14 17:12:01 +00:00
Title string
Year string
ImdbId string
SearchType string
}
2014-09-28 18:07:05 +00:00
//SearchResult is the type for the search results
2014-09-21 17:48:10 +00:00
type SearchResult struct {
Title string
Year string
2014-09-28 18:07:05 +00:00
ImdbID string
2014-09-21 17:48:10 +00:00
Type string
}
2014-09-28 18:07:05 +00:00
//SearchResponse is the struct of the response in a search
2014-09-21 17:48:10 +00:00
type SearchResponse struct {
Search []SearchResult
Response string
Error string
totalResults int
2014-09-21 17:48:10 +00:00
}
2014-09-28 18:07:05 +00:00
//MovieResult is the result struct of an specific movie search
2014-09-21 17:48:10 +00:00
type MovieResult struct {
Title string
Year string
Rated string
Released string
Runtime string
Genre string
Director string
Writer string
Actors string
Plot string
Language string
Country string
Awards string
Poster string
Metascore string
2014-09-21 20:24:51 +00:00
ImdbRating string
ImdbVotes string
ImdbID string
2014-09-21 17:48:10 +00:00
Type string
2014-09-21 20:24:51 +00:00
TomatoMeter string
TomatoImage string
TomatoRating string
TomatoReviews string
TomatoFresh string
TomatoRotten string
TomatoConsensus string
TomatoUserMeter string
TomatoUserRating string
TomatoUserReviews string
2016-02-08 21:00:13 +00:00
TomatoURL string
2014-09-21 17:48:10 +00:00
DVD string
BoxOffice string
Production string
Website string
Response string
Error string
}
//Search for movies given a Title and year, Year is optional you can pass nil
func Search(query *QueryData) (*SearchResponse, error) {
2016-06-14 17:12:01 +00:00
resp, err := requestAPI("search", query.Title, query.Year, query.SearchType)
2014-09-21 17:48:10 +00:00
if err != nil {
return nil, err
}
2014-09-25 17:31:39 +00:00
defer resp.Body.Close()
2014-09-21 17:48:10 +00:00
r := new(SearchResponse)
err = json.NewDecoder(resp.Body).Decode(r)
2014-09-21 17:48:10 +00:00
if err != nil {
return nil, err
}
if r.Response == "False" {
return r, errors.New(r.Error)
}
return r, nil
}
2015-07-17 20:16:57 +00:00
//MovieByTitle returns a MovieResult given Title
func MovieByTitle(query *QueryData) (*MovieResult, error) {
2016-06-14 17:12:01 +00:00
resp, err := requestAPI("title", query.Title, query.Year, query.SearchType)
2014-09-21 17:48:10 +00:00
if err != nil {
return nil, err
}
2014-09-25 17:31:39 +00:00
defer resp.Body.Close()
2014-09-21 17:48:10 +00:00
r := new(MovieResult)
err = json.NewDecoder(resp.Body).Decode(r)
2014-09-21 17:48:10 +00:00
if err != nil {
return nil, err
}
if r.Response == "False" {
return r, errors.New(r.Error)
}
return r, nil
}
2015-07-17 20:16:57 +00:00
//MovieByImdbID returns a MovieResult given a ImdbID ex:"tt2015381"
func MovieByImdbID(id string) (*MovieResult, error) {
resp, err := requestAPI("id", id)
2014-09-21 17:48:10 +00:00
if err != nil {
return nil, err
}
2014-09-25 17:31:39 +00:00
defer resp.Body.Close()
2014-09-21 17:48:10 +00:00
r := new(MovieResult)
err = json.NewDecoder(resp.Body).Decode(r)
2014-09-21 17:48:10 +00:00
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 requestAPI(apiCategory string, params ...string) (resp *http.Response, err error) {
2014-09-28 18:10:53 +00:00
var URL *url.URL
URL, err = url.Parse(baseURL)
if err != nil {
return nil, err
}
2016-06-15 06:59:01 +00:00
// 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])
}
}
2014-09-28 18:10:53 +00:00
URL.Path += "/"
parameters := url.Values{}
switch apiCategory {
case "search":
parameters.Add("s", params[0])
parameters.Add("y", params[1])
2016-06-14 17:12:01 +00:00
parameters.Add("type", params[2])
case "title":
parameters.Add("t", params[0])
parameters.Add("y", params[1])
2016-06-15 06:48:48 +00:00
parameters.Add("type", params[2])
parameters.Add("plot", plot)
parameters.Add("tomatoes", tomatoes)
case "id":
parameters.Add("i", params[0])
parameters.Add("plot", plot)
parameters.Add("tomatoes", tomatoes)
2014-09-21 17:48:10 +00:00
}
2014-09-28 18:10:53 +00:00
URL.RawQuery = parameters.Encode()
res, err := http.Get(URL.String())
2015-07-17 20:16:57 +00:00
err = checkErr(res.StatusCode)
2014-09-21 17:48:10 +00:00
if err != nil {
return nil, err
}
return res, nil
}
2015-07-17 20:16:57 +00:00
func checkErr(status int) error {
2014-09-21 17:48:10 +00:00
if status != 200 {
2014-09-28 18:07:05 +00:00
return fmt.Errorf("Status Code %d received from IMDB", status)
2014-09-21 17:48:10 +00:00
}
2014-09-28 18:07:05 +00:00
return nil
2014-09-21 17:48:10 +00:00
}
2014-09-21 20:50:45 +00:00
//Stringer Interface for MovieResult
func (mr MovieResult) String() string {
return fmt.Sprintf("#%s: %s (%s)", mr.ImdbID, mr.Title, mr.Year)
}
2014-09-21 20:55:44 +00:00
//Stringer Interface for SearchResult
2014-09-21 20:50:45 +00:00
func (sr SearchResult) String() string {
2014-09-28 18:07:05 +00:00
return fmt.Sprintf("#%s: %s (%s) Type: %s", sr.ImdbID, sr.Title, sr.Year, sr.Type)
2014-09-21 20:50:45 +00:00
}