gmantaos/Goirate

View on GitHub
src/movies/omdb.go

Summary

Maintainability
A
0 mins
Test Coverage
package movies

import (
    "fmt"
    "net/url"
    "os"
    "strconv"
    "strings"

    "goirate/utils"
)

type apiEndpoint string

const (
    baseEndpoint apiEndpoint = "https://www.omdbapi.com"
)

// OMDBCredentials holds the API key for access to the OMDB API.
type OMDBCredentials struct {
    APIKey string `toml:"api_key"`
}

// IsEnabled returns true if an API key has been provided for the OMDb API.
func (omdb *OMDBCredentials) IsEnabled() bool {

    if omdb.APIKey == "" {

        envCred := EnvOMDBCredentials()
        omdb.APIKey = envCred.APIKey
    }

    return omdb.APIKey != ""
}

// GetMovie fetches a movie using the OMDB API.
func (omdb *OMDBCredentials) GetMovie(imdbID string) (*Movie, error) {

    var omdbMovieResponse struct {
        ImdbID  string `json:"imdbID"`
        Title   string `json:"Title"`
        Year    string `json:"Year"`
        Runtime string `json:"Runtime"`
        Genres  string `json:"Genre"`
        Rating  string `json:"imdbRating"`
        Poster  string `json:"Poster"`
    }

    formattedID, err := FormatIMDbID(imdbID)

    if err != nil {
        return nil, err
    }

    baseURL, err := omdb.getRequestBaseURL()

    if err != nil {
        return nil, err
    }

    reqURL := fmt.Sprintf("%v&i=%v", baseURL, formattedID)

    httpClient := utils.HTTPClient{}

    err = httpClient.GetJSON(reqURL, &omdbMovieResponse)

    if err != nil {
        return nil, err
    }

    year, _ := strconv.Atoi(omdbMovieResponse.Year)
    duration, _ := strconv.Atoi(strings.Split(omdbMovieResponse.Runtime, " ")[0])
    rating, _ := strconv.ParseFloat(omdbMovieResponse.Rating, 32)
    genres := strings.Split(omdbMovieResponse.Genres, ", ")

    movie := Movie{
        MovieID: MovieID{
            IMDbID:   omdbMovieResponse.ImdbID,
            Title:    omdbMovieResponse.Title,
            Year:     uint(year),
            AltTitle: "",
        },
        Duration:  duration,
        Rating:    float32(rating),
        PosterURL: omdbMovieResponse.Poster,
        Genres:    genres,
    }

    return &movie, nil
}

// Search searches for a movie on the OMDb API, given a string as query.
func (omdb *OMDBCredentials) Search(query string) ([]MovieID, error) {

    var omdbSearchResponse struct {
        Search []struct {
            ImdbID string `json:"imdbID"`
            Title  string `json:"Title"`
            Year   string `json:"Year"`
        } `json:"Search"`
    }

    baseURL, err := omdb.getRequestBaseURL()

    if err != nil {
        return nil, err
    }

    formattedQuery := url.QueryEscape(query)

    reqURL := fmt.Sprintf("%v&s=%v", baseURL, formattedQuery)

    httpClient := utils.HTTPClient{}

    err = httpClient.GetJSON(reqURL, &omdbSearchResponse)

    if err != nil {
        return nil, err
    }

    var movies []MovieID

    for _, movie := range omdbSearchResponse.Search {

        year, _ := strconv.Atoi(movie.Year)

        movies = append(movies, MovieID{
            IMDbID:   movie.ImdbID,
            Title:    movie.Title,
            Year:     uint(year),
            AltTitle: "",
        })
    }

    return movies, nil
}

func (omdb *OMDBCredentials) getRequestBaseURL() (string, error) {

    envCred := EnvOMDBCredentials()

    if envCred.APIKey != "" && omdb.APIKey == "" {

        omdb.APIKey = envCred.APIKey
    }

    if omdb.APIKey == "" {

        return "", fmt.Errorf("fetching movie data requires an API key for OMDB. (http://www.omdbapi.com/apikey.aspx)")
    }

    baseURL := fmt.Sprintf("%v/?apikey=%v", baseEndpoint, omdb.APIKey)

    return baseURL, nil
}

// EnvOMDBCredentials returns an OMDBCredentials struct variable which contains
// the credentials found in the TVDB_API_KEY.
func EnvOMDBCredentials() OMDBCredentials {
    return OMDBCredentials{
        APIKey: os.Getenv("GOIRATE_OMDB_API_KEY"),
    }
}