* gifs service

* Commit from GitHub Actions (Publish APIs & Clients)

Co-authored-by: domwong <domwong@users.noreply.github.com>
This commit is contained in:
Dominic Wong
2021-10-06 17:48:31 +01:00
committed by GitHub
parent 6847149fdf
commit 93059dcfa0
23 changed files with 2223 additions and 2 deletions

147
gifs/handler/gifs.go Normal file
View File

@@ -0,0 +1,147 @@
package handler
import (
"context"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"strconv"
"github.com/micro/micro/v3/service/config"
"github.com/micro/micro/v3/service/errors"
"github.com/micro/micro/v3/service/logger"
gifs "github.com/micro/services/gifs/proto"
)
const (
giphySearch = "https://api.giphy.com/v1/gifs/search?api_key=%s&q=%s&limit=%d&offset=%d&rating=%s&lang=%s"
defaultLimit int32 = 25
defaultOffset int32 = 0
defaultRating = "g"
defaultLang = "en"
)
type conf struct {
APIKey string `json:"api_key"`
}
type Gifs struct {
conf conf
}
func New() *Gifs {
v, err := config.Get("micro.gifs")
if err != nil {
logger.Fatalf("Failed to load config %s", err)
}
var c conf
if err := v.Scan(&c); err != nil {
logger.Fatalf("Failed to load config %s", err)
}
return &Gifs{conf: c}
}
func (g *Gifs) Search(ctx context.Context, request *gifs.SearchRequest, response *gifs.SearchResponse) error {
if len(request.Query) == 0 {
return errors.BadRequest("gifs.Search", "Missing query field")
}
limit := defaultLimit
if request.Limit > 0 {
limit = request.Limit
}
offset := defaultOffset
if request.Offset > 0 {
offset = request.Offset
}
rating := defaultRating
if len(request.Rating) > 0 {
rating = request.Rating
}
lan := defaultLang
if len(request.Lang) > 0 {
lan = request.Lang
}
rsp, err := http.Get(fmt.Sprintf(giphySearch, g.conf.APIKey, request.Query, limit, offset, rating, lan))
if err != nil {
logger.Errorf("Error querying giphy %s", err)
return errors.InternalServerError("gifs.Search", "Error querying for gifs")
}
defer rsp.Body.Close()
b, err := ioutil.ReadAll(rsp.Body)
if err != nil {
logger.Errorf("Error marshalling giphy response %s", err)
return errors.InternalServerError("gifs.Search", "Error querying for gifs")
}
var gRsp searchResponse
if err := json.Unmarshal(b, &gRsp); err != nil {
logger.Errorf("Error marshalling giphy response %s", err)
return errors.InternalServerError("gifs.Search", "Error querying for gifs")
}
response.Data = marshalGifs(gRsp.Data)
response.Pagination = &gifs.Pagination{
Offset: gRsp.Pagination.Offset,
TotalCount: gRsp.Pagination.TotalCount,
Count: gRsp.Pagination.Count,
}
return nil
}
func marshalGifs(in []gif) []*gifs.Gif {
ret := make([]*gifs.Gif, len(in))
for i, v := range in {
ret[i] = &gifs.Gif{
Id: v.ID,
Slug: v.Slug,
Url: v.URL,
ShortUrl: v.ShortURL,
EmbedUrl: v.EmbedURL,
Source: v.Source,
Rating: v.Rating,
Title: v.Title,
Images: &gifs.ImageFormats{
Original: marshalImageFormat(v.Images.Original),
Downsized: marshalImageFormat(v.Images.Downsized),
FixedHeight: marshalImageFormat(v.Images.FixedHeight),
FixedHeightStill: marshalImageFormat(v.Images.FixedHeightStill),
FixedHeightDownsampled: marshalImageFormat(v.Images.FixedHeightDownsampled),
FixedWidth: marshalImageFormat(v.Images.FixedWidth),
FixedWidthStill: marshalImageFormat(v.Images.FixedWidthStill),
FixedWidthDownsampled: marshalImageFormat(v.Images.FixedWidthDownsampled),
FixedHeightSmall: marshalImageFormat(v.Images.FixedHeightSmall),
FixedHeightSmallStill: marshalImageFormat(v.Images.FixedHeightSmallStill),
FixedWidthSmall: marshalImageFormat(v.Images.FixedWidthSmall),
FixedWidthSmallStill: marshalImageFormat(v.Images.FixedWidthSmallStill),
DownsizedStill: marshalImageFormat(v.Images.DownsizedStill),
DownsizedLarge: marshalImageFormat(v.Images.DownsizedLarge),
DownsizedMedium: marshalImageFormat(v.Images.DownsizedMedium),
DownsizedSmall: marshalImageFormat(v.Images.DownsizedSmall),
OriginalStill: marshalImageFormat(v.Images.OriginalStill),
Looping: marshalImageFormat(v.Images.Looping),
Preview: marshalImageFormat(v.Images.Preview),
PreviewGif: marshalImageFormat(v.Images.PreviewGif),
},
}
}
return ret
}
func marshalImageFormat(in format) *gifs.ImageFormat {
mustInt32 := func(s string) int32 {
i, _ := strconv.Atoi(s)
return int32(i)
}
return &gifs.ImageFormat{
Height: mustInt32(in.Height),
Width: mustInt32(in.Width),
Size: mustInt32(in.Size),
Url: in.URL,
Mp4Url: in.MP4URL,
Mp4Size: mustInt32(in.MP4Size),
WebpUrl: in.WebpURL,
WebpSize: mustInt32(in.WebpSize),
}
}

58
gifs/handler/types.go Normal file
View File

@@ -0,0 +1,58 @@
package handler
type searchResponse struct {
Data []gif `json:"data"`
Pagination pagination `json:"pagination"`
}
type gif struct {
ID string `json:"id"`
Slug string `json:"slug"`
URL string `json:"url"`
ShortURL string `json:"bitly_url"`
EmbedURL string `json:"embed_url"`
Source string `json:"source"`
Rating string `json:"rating"`
Images formats `json:"images"`
Title string `json:"title"`
}
type formats struct {
Original format `json:"original"`
Downsized format `json:"downsized"`
FixedHeight format `json:"fixed_height"`
FixedHeightStill format `json:"fixed_height_still"`
FixedHeightDownsampled format `json:"fixed_height_downsampled"`
FixedWidth format `json:"fixed_width"`
FixedWidthStill format `json:"fixed_width_still"`
FixedWidthDownsampled format `json:"fixed_width_downsampled"`
FixedHeightSmall format `json:"fixed_height_small"`
FixedHeightSmallStill format `json:"fixed_height_small_still"`
FixedWidthSmall format `json:"fixed_width_small"`
FixedWidthSmallStill format `json:"fixed_width_small_still"`
DownsizedStill format `json:"downsized_still"`
DownsizedLarge format `json:"downsized_large"`
DownsizedMedium format `json:"downsized_medium"`
DownsizedSmall format `json:"downsized_small"`
OriginalStill format `json:"original_still"`
Looping format `json:"looping"`
Preview format `json:"preview"`
PreviewGif format `json:"preview_gif"`
}
type format struct {
Height string `json:"height"`
Width string `json:"width"`
Size string `json:"size"`
URL string `json:"url"`
MP4URL string `json:"mp4_url"`
MP4Size string `json:"mp4_size"`
WebpURL string `json:"webp_url"`
WebpSize string `json:"webp_size"`
}
type pagination struct {
Offset int32 `json:"offset"`
TotalCount int32 `json:"total_count"`
Count int32 `json:"count"`
}