mirror of
https://github.com/kevin-DL/services.git
synced 2026-01-11 19:04:35 +00:00
* feat: add movie search service close #183 * chore: update display name * chore: code review fix * feat: avoid panic when fields would be null or missed * chore: make it more readable * fix: correct format
139 lines
3.5 KiB
Go
139 lines
3.5 KiB
Go
package handler
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"net/http"
|
|
"net/url"
|
|
|
|
"github.com/micro/micro/v3/service/config"
|
|
"github.com/micro/micro/v3/service/errors"
|
|
"github.com/micro/micro/v3/service/logger"
|
|
|
|
pb "github.com/micro/services/movie/proto"
|
|
)
|
|
|
|
type Movie struct {
|
|
Api string
|
|
Key string
|
|
}
|
|
|
|
func New() *Movie {
|
|
v, err := config.Get("movie.api")
|
|
if err != nil {
|
|
logger.Fatal("movie.api config not found: %v", err)
|
|
}
|
|
|
|
api := v.String("")
|
|
if len(api) == 0 {
|
|
logger.Fatal("movie.api config not found")
|
|
}
|
|
|
|
v, err = config.Get("movie.key")
|
|
if err != nil {
|
|
logger.Fatal("movie.key config not found: %v", err)
|
|
}
|
|
|
|
key := v.String("")
|
|
if len(key) == 0 {
|
|
logger.Fatal("movie.key config not found")
|
|
}
|
|
|
|
return &Movie{
|
|
Api: api,
|
|
Key: key,
|
|
}
|
|
}
|
|
|
|
func (m *Movie) Search(_ context.Context, req *pb.SearchRequest, rsp *pb.SearchResponse) error {
|
|
if req.Page == 0 {
|
|
req.Page = 1
|
|
}
|
|
|
|
vals := url.Values{}
|
|
vals.Set("api_key", m.Key)
|
|
vals.Set("query", req.Query)
|
|
vals.Set("language", req.Language)
|
|
vals.Set("page", fmt.Sprintf("%d", req.Page))
|
|
vals.Set("include_adult", "false")
|
|
vals.Set("region", req.Region)
|
|
if req.Year > 0 {
|
|
vals.Set("year", fmt.Sprintf("%d", req.Year))
|
|
}
|
|
if req.PrimaryReleaseYear > 0 {
|
|
vals.Set("primary_release_year", fmt.Sprintf("%d", req.PrimaryReleaseYear))
|
|
}
|
|
|
|
api := fmt.Sprintf("%s/search/movie?%s", m.Api, vals.Encode())
|
|
|
|
resp, err := http.Get(api)
|
|
if err != nil {
|
|
logger.Errorf("Failed to get movie search results: %v\n", err)
|
|
return errors.InternalServerError("movie.search", "failed to get movie search results")
|
|
}
|
|
|
|
if resp.StatusCode != http.StatusOK {
|
|
logger.Errorf("Movie search api status code is not OK! status=%d\n", resp.StatusCode)
|
|
return errors.InternalServerError("movie.search", fmt.Sprintf("movie search status is not 200, it's %d", resp.StatusCode))
|
|
}
|
|
|
|
defer func() {
|
|
if err := resp.Body.Close(); err != nil {
|
|
logger.Errorf("Movie search close response body error: %v\n", err)
|
|
}
|
|
}()
|
|
|
|
b, _ := ioutil.ReadAll(resp.Body)
|
|
|
|
var respBody map[string]interface{}
|
|
|
|
if err := json.Unmarshal(b, &respBody); err != nil {
|
|
logger.Errorf("Failed to unmarshal movie search results: %v\n", err)
|
|
return errors.InternalServerError("movie.search", "failed to unmarshal movie search results")
|
|
}
|
|
|
|
rsp.Page = int32(respBody["page"].(float64))
|
|
rsp.TotalPages = int32(respBody["total_pages"].(float64))
|
|
rsp.TotalResults = int32(respBody["total_results"].(float64))
|
|
|
|
results := respBody["results"].([]interface{})
|
|
|
|
for _, v := range results {
|
|
info := v.(map[string]interface{})
|
|
|
|
genreIds := make([]int32, 0)
|
|
if ids, ok := info["genre_ids"].([]interface{}); ok {
|
|
for _, id := range ids {
|
|
genreIds = append(genreIds, int32(id.(float64)))
|
|
}
|
|
}
|
|
|
|
mi := &pb.MovieInfo{}
|
|
|
|
id, _ := info["id"].(float64)
|
|
mi.Id = int32(id)
|
|
|
|
voteCount, _ := info["vote_count"].(float64)
|
|
mi.VoteCount = int32(voteCount)
|
|
|
|
mi.PosterPath, _ = info["poster_path"].(string)
|
|
mi.Adult, _ = info["adult"].(bool)
|
|
mi.Overview, _ = info["overview"].(string)
|
|
mi.ReleaseDate, _ = info["release_date"].(string)
|
|
mi.GenreIds = genreIds
|
|
mi.OriginalTitle, _ = info["original_title"].(string)
|
|
mi.OriginalLanguage, _ = info["original_language"].(string)
|
|
mi.Title, _ = info["title"].(string)
|
|
mi.BackdropPath, _ = info["poster_path"].(string)
|
|
mi.Popularity, _ = info["popularity"].(float64)
|
|
mi.Video, _ = info["video"].(bool)
|
|
mi.VoteAverage, _ = info["vote_average"].(float64)
|
|
|
|
rsp.Results = append(rsp.Results, mi)
|
|
}
|
|
|
|
return nil
|
|
}
|