github.com/andrew00x/gomovies@v0.1.0/pkg/service/service_details.go (about)

     1  package service
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/andrew00x/gomovies/pkg/api"
     7  	"github.com/andrew00x/gomovies/pkg/config"
     8  	"github.com/andrew00x/gomovies/pkg/details"
     9  	"github.com/andrew00x/gomovies/pkg/tmdb"
    10  	"github.com/andrew00x/gomovies/pkg/util"
    11  )
    12  
    13  type DetailsService struct {
    14  	tmdbLoader  *tmdbLoader
    15  	localLoader *localLoader
    16  }
    17  
    18  func CreateDetailsService(conf *config.Config) (srv *DetailsService, err error) {
    19  	if conf.TMDbApiKey == "" {
    20  		srv = &DetailsService{
    21  			tmdbLoader: nil,
    22  			localLoader: &localLoader{
    23  				cache: util.CreateCache(),
    24  			},
    25  		}
    26  	} else {
    27  		tmdbConn := tmdb.GetTmDbInstance(conf.TMDbApiKey)
    28  		var tmdbConf tmdb.Config
    29  		tmdbConf, err = tmdbConn.GetConfiguration()
    30  		if err != nil {
    31  			return
    32  		}
    33  		srv = &DetailsService{
    34  			tmdbLoader: &tmdbLoader{
    35  				conf:     conf,
    36  				tmdbConf: tmdbConf,
    37  				tmdbConn: tmdbConn,
    38  				cache:    util.CreateCache(),
    39  			},
    40  			localLoader: &localLoader{
    41  				cache: util.CreateCache(),
    42  			},
    43  		}
    44  	}
    45  	return
    46  }
    47  
    48  func (srv *DetailsService) MovieDetails(m api.Movie, lang string, tryLoad bool) (api.MovieDetails, bool, error) {
    49  	if m.TMDbId != 0 && srv.tmdbLoader != nil {
    50  		return srv.tmdbLoader.load(m, lang, tryLoad)
    51  	}
    52  	return srv.localLoader.load(m, lang, tryLoad)
    53  }
    54  
    55  func (srv *DetailsService) SearchDetails(query, lang string) ([]api.MovieDetails, error) {
    56  	if srv.tmdbLoader != nil {
    57  		result, err := srv.tmdbLoader.tmdbConn.SearchMovies(query, lang)
    58  		if err == nil {
    59  			movies := make([]api.MovieDetails, 0, len(result))
    60  			for _, tmDbMovie := range result {
    61  				movies = append(movies,
    62  					api.MovieDetails{
    63  						OriginalTitle:  tmDbMovie.OriginalTitle,
    64  						Overview:       tmDbMovie.Overview,
    65  						PosterSmallUrl: fmt.Sprintf("%s%s%s", srv.tmdbLoader.tmdbConf.Images.BaseUrl, srv.tmdbLoader.conf.TMDbPosterSmall, tmDbMovie.PosterPath),
    66  						PosterLargeUrl: fmt.Sprintf("%s%s%s", srv.tmdbLoader.tmdbConf.Images.BaseUrl, srv.tmdbLoader.conf.TMDbPosterLarge, tmDbMovie.PosterPath),
    67  						ReleaseDate:    tmDbMovie.ReleaseDate,
    68  						TMDbId:         tmDbMovie.Id,
    69  					})
    70  			}
    71  			return movies, nil
    72  		}
    73  		return nil, err
    74  	}
    75  	return nil, nil
    76  }
    77  
    78  type localDetailsKey struct {
    79  	file string
    80  	lang string
    81  }
    82  
    83  type localLoader struct {
    84  	cache util.Cache
    85  }
    86  
    87  func (l *localLoader) load(m api.Movie, lang string, tryLoad bool) (md api.MovieDetails, found bool, err error) {
    88  	var v interface{}
    89  	if tryLoad {
    90  		v, err = l.cache.GetOrLoad(localDetailsKey{file: m.File, lang: lang}, func(key util.Key) (interface{}, error) {
    91  			k := key.(localDetailsKey)
    92  			return details.GetDetails(k.file, k.lang)
    93  		})
    94  	} else {
    95  		v, err = l.cache.Get(localDetailsKey{file: m.File, lang: lang})
    96  	}
    97  	if err == nil && v != nil {
    98  		found = true
    99  		md = v.(api.MovieDetails)
   100  	}
   101  	return
   102  }
   103  
   104  type tmdbDetailsKey struct {
   105  	id   int
   106  	lang string
   107  }
   108  
   109  type tmdbLoader struct {
   110  	conf     *config.Config
   111  	tmdbConf tmdb.Config
   112  	tmdbConn *tmdb.TmDb
   113  	cache    util.Cache
   114  }
   115  
   116  func (l *tmdbLoader) load(m api.Movie, lang string, tryLoad bool) (md api.MovieDetails, found bool, err error) {
   117  	var v interface{}
   118  	if tryLoad {
   119  		v, err = l.cache.GetOrLoad(tmdbDetailsKey{id: m.TMDbId, lang: lang}, func(key util.Key) (interface{}, error) {
   120  			k := key.(tmdbDetailsKey)
   121  			return l.tmdbConn.GetMovie(k.id, k.lang)
   122  		})
   123  	} else {
   124  		v, err = l.cache.Get(tmdbDetailsKey{id: m.TMDbId, lang: lang})
   125  	}
   126  	if err == nil && v != nil {
   127  		found = true
   128  		tmDbMovie := v.(tmdb.MovieDetails)
   129  		md = api.MovieDetails{
   130  			Budget:         tmDbMovie.Budget,
   131  			Companies:      companyNames(tmDbMovie.ProductionCompanies),
   132  			Countries:      countryNames(tmDbMovie.ProductionCountries),
   133  			Genres:         genreNames(tmDbMovie.Genres),
   134  			OriginalTitle:  tmDbMovie.OriginalTitle,
   135  			Overview:       tmDbMovie.Overview,
   136  			PosterSmallUrl: fmt.Sprintf("%s%s%s", l.tmdbConf.Images.BaseUrl, l.conf.TMDbPosterSmall, tmDbMovie.PosterPath),
   137  			PosterLargeUrl: fmt.Sprintf("%s%s%s", l.tmdbConf.Images.BaseUrl, l.conf.TMDbPosterLarge, tmDbMovie.PosterPath),
   138  			Runtime:        tmDbMovie.Runtime,
   139  			ReleaseDate:    tmDbMovie.ReleaseDate,
   140  			Revenue:        tmDbMovie.Revenue,
   141  			TagLine:        tmDbMovie.TagLine,
   142  			Title:          tmDbMovie.Title,
   143  			TMDbId:         tmDbMovie.Id,
   144  		}
   145  	}
   146  	return
   147  }
   148  
   149  func companyNames(companies []tmdb.Company) []string {
   150  	names := make([]string, 0, len(companies))
   151  	for _, c := range companies {
   152  		names = append(names, c.Name)
   153  	}
   154  	return names
   155  }
   156  
   157  func countryNames(countries []tmdb.Country) []string {
   158  	names := make([]string, 0, len(countries))
   159  	for _, c := range countries {
   160  		names = append(names, c.Name)
   161  	}
   162  	return names
   163  }
   164  
   165  func genreNames(genres []tmdb.Genre) []string {
   166  	names := make([]string, 0, len(genres))
   167  	for _, c := range genres {
   168  		names = append(names, c.Name)
   169  	}
   170  	return names
   171  }