* 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

135
clients/go/gifs/gifs.go Executable file
View File

@@ -0,0 +1,135 @@
package gifs
import (
"github.com/m3o/m3o-go/client"
)
func NewGifsService(token string) *GifsService {
return &GifsService{
client: client.NewClient(&client.Options{
Token: token,
}),
}
}
type GifsService struct {
client *client.Client
}
// Search for a gif
func (t *GifsService) Search(request *SearchRequest) (*SearchResponse, error) {
rsp := &SearchResponse{}
return rsp, t.client.Call("gifs", "Search", request, rsp)
}
type Gif struct {
// URL used for embedding the GIF
EmbedUrl string `json:"embedUrl"`
// The ID of the GIF
Id string `json:"id"`
// The different formats available for this GIF
Images *ImageFormats `json:"images"`
// The content rating for the GIF
Rating string `json:"rating"`
// A short URL for this GIF
ShortUrl string `json:"shortUrl"`
// The slug used in the GIF's URL
Slug string `json:"slug"`
// The page on which this GIF was found
Source string `json:"source"`
// The title for this GIF
Title string `json:"title"`
// The URL for this GIF
Url string `json:"url"`
}
type ImageFormat struct {
// height
Height int32 `json:"height"`
// size of the MP4 version
Mp4size int32 `json:"mp4size"`
// URL to an MP4 version of the gif
Mp4url string `json:"mp4url"`
// size in bytes
Size int32 `json:"size"`
// URL of the gif
Url string `json:"url"`
// size of the webp version
WebpSize int32 `json:"webpSize"`
// URL to a webp version of the gif
WebpUrl string `json:"webpUrl"`
// width
Width int32 `json:"width"`
}
type ImageFormats struct {
// A downsized version of the GIF < 2MB
Downsized *ImageFormat `json:"downsized"`
// A downsized version of the GIF < 8MB
DownsizedLarge *ImageFormat `json:"downsizedLarge"`
// A downsized version of the GIF < 5MB
DownsizedMedium *ImageFormat `json:"downsizedMedium"`
// A downsized version of the GIF < 200kb
DownsizedSmall *ImageFormat `json:"downsizedSmall"`
// Static image of the downsized version of the GIF
DownsizedStill *ImageFormat `json:"downsizedStill"`
// Version of the GIF with fixed height of 200 pixels. Good for mobile use
FixedHeight *ImageFormat `json:"fixedHeight"`
// Version of the GIF with fixed height of 200 pixels and number of frames reduced to 6
FixedHeightDownsampled *ImageFormat `json:"fixedHeightDownsampled"`
// Version of the GIF with fixed height of 100 pixels. Good for mobile keyboards
FixedHeightSmall *ImageFormat `json:"fixedHeightSmall"`
// Static image of the GIF with fixed height of 100 pixels
FixedHeightSmallStill *ImageFormat `json:"fixedHeightSmallStill"`
// Static image of the GIF with fixed height of 200 pixels
FixedHeightStill *ImageFormat `json:"fixedHeightStill"`
// Version of the GIF with fixed width of 200 pixels. Good for mobile use
FixedWidth *ImageFormat `json:"fixedWidth"`
// Version of the GIF with fixed width of 200 pixels and number of frames reduced to 6
FixedWidthDownsampled *ImageFormat `json:"fixedWidthDownsampled"`
// Version of the GIF with fixed width of 100 pixels. Good for mobile keyboards
FixedWidthSmall *ImageFormat `json:"fixedWidthSmall"`
// Static image of the GIF with fixed width of 100 pixels
FixedWidthSmallStill *ImageFormat `json:"fixedWidthSmallStill"`
// Static image of the GIF with fixed width of 200 pixels
FixedWidthStill *ImageFormat `json:"fixedWidthStill"`
// 15 second version of the GIF looping
Looping *ImageFormat `json:"looping"`
// The original GIF. Good for desktop use
Original *ImageFormat `json:"original"`
// Static image of the original version of the GIF
OriginalStill *ImageFormat `json:"originalStill"`
// mp4 version of the GIF <50kb displaying first 1-2 secs
Preview *ImageFormat `json:"preview"`
// Version of the GIF <50kb displaying first 1-2 secs
PreviewGif *ImageFormat `json:"previewGif"`
}
type Pagination struct {
// total number returned in this response
Count int32 `json:"count"`
// position in pagination
Offset int32 `json:"offset"`
// total number of results available
TotalCount int32 `json:"totalCount"`
}
type SearchRequest struct {
// ISO 2 letter language code for regional content
Lang string `json:"lang"`
// Max number of gifs to return. Defaults to 25
Limit int32 `json:"limit"`
// The start position of results (used with pagination)
Offset int32 `json:"offset"`
// The search term
Query string `json:"query"`
// Apply age related content filter. "g", "pg", "pg-13", or "r". Defaults to "g"
Rating string `json:"rating"`
}
type SearchResponse struct {
// list of results
Data []Gif `json:"data"`
// information on pagination
Pagination *Pagination `json:"pagination"`
}

View File

@@ -13,6 +13,7 @@ import (
"github.com/micro/services/clients/go/file"
"github.com/micro/services/clients/go/forex"
"github.com/micro/services/clients/go/geocoding"
"github.com/micro/services/clients/go/gifs"
"github.com/micro/services/clients/go/helloworld"
"github.com/micro/services/clients/go/holidays"
"github.com/micro/services/clients/go/id"
@@ -57,6 +58,7 @@ func NewClient(token string) *Client {
FileService: file.NewFileService(token),
ForexService: forex.NewForexService(token),
GeocodingService: geocoding.NewGeocodingService(token),
GifsService: gifs.NewGifsService(token),
HelloworldService: helloworld.NewHelloworldService(token),
HolidaysService: holidays.NewHolidaysService(token),
IdService: id.NewIdService(token),
@@ -101,6 +103,7 @@ type Client struct {
FileService *file.FileService
ForexService *forex.ForexService
GeocodingService *geocoding.GeocodingService
GifsService *gifs.GifsService
HelloworldService *helloworld.HelloworldService
HolidaysService *holidays.HolidaysService
IdService *id.IdService

129
clients/ts/gifs/index.ts Executable file
View File

@@ -0,0 +1,129 @@
import * as m3o from "@m3o/m3o-node";
export class GifsService {
private client: m3o.Client;
constructor(token: string) {
this.client = new m3o.Client({ token: token });
}
// Search for a gif
search(request: SearchRequest): Promise<SearchResponse> {
return this.client.call(
"gifs",
"Search",
request
) as Promise<SearchResponse>;
}
}
export interface Gif {
// URL used for embedding the GIF
embedUrl?: string;
// The ID of the GIF
id?: string;
// The different formats available for this GIF
images?: ImageFormats;
// The content rating for the GIF
rating?: string;
// A short URL for this GIF
shortUrl?: string;
// The slug used in the GIF's URL
slug?: string;
// The page on which this GIF was found
source?: string;
// The title for this GIF
title?: string;
// The URL for this GIF
url?: string;
}
export interface ImageFormat {
// height
height?: number;
// size of the MP4 version
mp4Size?: number;
// URL to an MP4 version of the gif
mp4Url?: string;
// size in bytes
size?: number;
// URL of the gif
url?: string;
// size of the webp version
webpSize?: number;
// URL to a webp version of the gif
webpUrl?: string;
// width
width?: number;
}
export interface ImageFormats {
// A downsized version of the GIF < 2MB
downsized?: ImageFormat;
// A downsized version of the GIF < 8MB
downsizedLarge?: ImageFormat;
// A downsized version of the GIF < 5MB
downsizedMedium?: ImageFormat;
// A downsized version of the GIF < 200kb
downsizedSmall?: ImageFormat;
// Static image of the downsized version of the GIF
downsizedStill?: ImageFormat;
// Version of the GIF with fixed height of 200 pixels. Good for mobile use
fixedHeight?: ImageFormat;
// Version of the GIF with fixed height of 200 pixels and number of frames reduced to 6
fixedHeightDownsampled?: ImageFormat;
// Version of the GIF with fixed height of 100 pixels. Good for mobile keyboards
fixedHeightSmall?: ImageFormat;
// Static image of the GIF with fixed height of 100 pixels
fixedHeightSmallStill?: ImageFormat;
// Static image of the GIF with fixed height of 200 pixels
fixedHeightStill?: ImageFormat;
// Version of the GIF with fixed width of 200 pixels. Good for mobile use
fixedWidth?: ImageFormat;
// Version of the GIF with fixed width of 200 pixels and number of frames reduced to 6
fixedWidthDownsampled?: ImageFormat;
// Version of the GIF with fixed width of 100 pixels. Good for mobile keyboards
fixedWidthSmall?: ImageFormat;
// Static image of the GIF with fixed width of 100 pixels
fixedWidthSmallStill?: ImageFormat;
// Static image of the GIF with fixed width of 200 pixels
fixedWidthStill?: ImageFormat;
// 15 second version of the GIF looping
looping?: ImageFormat;
// The original GIF. Good for desktop use
original?: ImageFormat;
// Static image of the original version of the GIF
originalStill?: ImageFormat;
// mp4 version of the GIF <50kb displaying first 1-2 secs
preview?: ImageFormat;
// Version of the GIF <50kb displaying first 1-2 secs
previewGif?: ImageFormat;
}
export interface Pagination {
// total number returned in this response
count?: number;
// position in pagination
offset?: number;
// total number of results available
totalCount?: number;
}
export interface SearchRequest {
// ISO 2 letter language code for regional content
lang?: string;
// Max number of gifs to return. Defaults to 25
limit?: number;
// The start position of results (used with pagination)
offset?: number;
// The search term
query?: string;
// Apply age related content filter. "g", "pg", "pg-13", or "r". Defaults to "g"
rating?: string;
}
export interface SearchResponse {
// list of results
data?: Gif[];
// information on pagination
pagination?: { [key: string]: any };
}

View File

@@ -10,6 +10,7 @@ import * as evchargers from "./evchargers";
import * as file from "./file";
import * as forex from "./forex";
import * as geocoding from "./geocoding";
import * as gifs from "./gifs";
import * as helloworld from "./helloworld";
import * as holidays from "./holidays";
import * as id from "./id";
@@ -51,6 +52,7 @@ export class Client {
this.fileService = new file.FileService(token);
this.forexService = new forex.ForexService(token);
this.geocodingService = new geocoding.GeocodingService(token);
this.gifsService = new gifs.GifsService(token);
this.helloworldService = new helloworld.HelloworldService(token);
this.holidaysService = new holidays.HolidaysService(token);
this.idService = new id.IdService(token);
@@ -91,6 +93,7 @@ export class Client {
fileService: file.FileService;
forexService: forex.ForexService;
geocodingService: geocoding.GeocodingService;
gifsService: gifs.GifsService;
helloworldService: helloworld.HelloworldService;
holidaysService: holidays.HolidaysService;
idService: id.IdService;

View File

@@ -21,6 +21,7 @@
"./file": "./dist/file/index.js",
"./forex": "./dist/forex/index.js",
"./geocoding": "./dist/geocoding/index.js",
"./gifs": "./dist/gifs/index.js",
"./helloworld": "./dist/helloworld/index.js",
"./holidays": "./dist/holidays/index.js",
"./id": "./dist/id/index.js",
@@ -64,5 +65,5 @@
},
"type": "module",
"types": "dist/index.d.ts",
"version": "1.0.539"
"version": "1.0.540"
}

View File

@@ -11,8 +11,8 @@ func UpdateArecord() {
dbService := db.NewDbService(os.Getenv("MICRO_API_TOKEN"))
rsp, err := dbService.Update(&db.UpdateRequest{
Record: map[string]interface{}{
"id": "1",
"age": 43,
"id": "1",
},
Table: "users",
})

View File

@@ -0,0 +1,7 @@
curl "https://api.m3o.com/v1/gifs/Search" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $MICRO_API_TOKEN" \
-d '{
"limit": 2,
"query": "dogs"
}'

View File

@@ -0,0 +1,17 @@
package example
import (
"fmt"
"github.com/micro/services/clients/go/gifs"
"os"
)
// Search for a gif
func Search() {
gifsService := gifs.NewGifsService(os.Getenv("MICRO_API_TOKEN"))
rsp, err := gifsService.Search(&gifs.SearchRequest{
Limit: 2,
Query: "dogs",
})
fmt.Println(rsp, err)
}

View File

@@ -0,0 +1,13 @@
import * as gifs from "m3o/gifs";
// Search for a gif
async function Search() {
let gifsService = new gifs.GifsService(process.env.MICRO_API_TOKEN);
let rsp = await gifsService.search({
limit: 2,
query: "dogs",
});
console.log(rsp);
}
await Search();

2
gifs/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
gifs

3
gifs/Dockerfile Normal file
View File

@@ -0,0 +1,3 @@
FROM alpine
ADD gifs /gifs
ENTRYPOINT [ "/gifs" ]

28
gifs/Makefile Normal file
View File

@@ -0,0 +1,28 @@
GOPATH:=$(shell go env GOPATH)
.PHONY: init
init:
go get -u github.com/golang/protobuf/proto
go get -u github.com/golang/protobuf/protoc-gen-go
go get github.com/micro/micro/v3/cmd/protoc-gen-micro
go get github.com/micro/micro/v3/cmd/protoc-gen-openapi
.PHONY: api
api:
protoc --openapi_out=. --proto_path=. proto/gifs.proto
.PHONY: proto
proto:
protoc --proto_path=. --micro_out=. --go_out=:. proto/gifs.proto
.PHONY: build
build:
go build -o gifs *.go
.PHONY: test
test:
go test -v ./... -cover
.PHONY: docker
docker:
docker build . -t gifs:latest

7
gifs/README.md Normal file
View File

@@ -0,0 +1,7 @@
Quick and simple GIF search
# Gifs Service
Add gifs to your project with keyword search and results in multiple sizes and formats.
Powered by [GIPHY](https://giphy.com).

447
gifs/examples.json Normal file
View File

@@ -0,0 +1,447 @@
{
"search": [
{
"title": "Search",
"description": "Search for gifs",
"run_check": false,
"request": {
"query": "dogs",
"limit": 2
},
"response": {
"data": [
{
"id": "gzBwhbjfjdZzIaO9En",
"slug": "studiosoriginals-gzBwhbjfjdZzIaO9En",
"url": "https://giphy.com/gifs/studiosoriginals-gzBwhbjfjdZzIaO9En",
"short_url": "https://gph.is/g/aKQ5Kr6",
"embed_url": "https://giphy.com/embed/gzBwhbjfjdZzIaO9En",
"source": "",
"rating": "g",
"title": "Miss You Reaction GIF by GIPHY Studios Originals",
"images": {
"original": {
"height": 480,
"width": 338,
"size": 726274,
"url": "https://media2.giphy.com/media/gzBwhbjfjdZzIaO9En/giphy.gif?cid=ea1d2e62g20a2z6zrxsyk0fhlbomzsm3hni8gz7ppq4625qc&rid=giphy.gif&ct=g",
"mp4_url": "",
"mp4_size": 541901,
"webp_url": "",
"webp_size": 337906
},
"downsized": {
"height": 480,
"width": 338,
"size": 726274,
"url": "https://media2.giphy.com/media/gzBwhbjfjdZzIaO9En/giphy.gif?cid=ea1d2e62g20a2z6zrxsyk0fhlbomzsm3hni8gz7ppq4625qc&rid=giphy.gif&ct=g",
"mp4_url": "",
"mp4_size": 0,
"webp_url": "",
"webp_size": 0
},
"fixed_height": {
"height": 200,
"width": 141,
"size": 157088,
"url": "https://media2.giphy.com/media/gzBwhbjfjdZzIaO9En/200.gif?cid=ea1d2e62g20a2z6zrxsyk0fhlbomzsm3hni8gz7ppq4625qc&rid=200.gif&ct=g",
"mp4_url": "",
"mp4_size": 89657,
"webp_url": "",
"webp_size": 91512
},
"fixed_height_still": {
"height": 200,
"width": 141,
"size": 12751,
"url": "https://media2.giphy.com/media/gzBwhbjfjdZzIaO9En/200_s.gif?cid=ea1d2e62g20a2z6zrxsyk0fhlbomzsm3hni8gz7ppq4625qc&rid=200_s.gif&ct=g",
"mp4_url": "",
"mp4_size": 0,
"webp_url": "",
"webp_size": 0
},
"fixed_height_downsampled": {
"height": 200,
"width": 141,
"size": 68558,
"url": "https://media2.giphy.com/media/gzBwhbjfjdZzIaO9En/200_d.gif?cid=ea1d2e62g20a2z6zrxsyk0fhlbomzsm3hni8gz7ppq4625qc&rid=200_d.gif&ct=g",
"mp4_url": "",
"mp4_size": 0,
"webp_url": "",
"webp_size": 45208
},
"fixed_width": {
"height": 284,
"width": 200,
"size": 263316,
"url": "https://media2.giphy.com/media/gzBwhbjfjdZzIaO9En/200w.gif?cid=ea1d2e62g20a2z6zrxsyk0fhlbomzsm3hni8gz7ppq4625qc&rid=200w.gif&ct=g",
"mp4_url": "",
"mp4_size": 156878,
"webp_url": "",
"webp_size": 155314
},
"fixed_width_still": {
"height": 284,
"width": 200,
"size": 16413,
"url": "https://media2.giphy.com/media/gzBwhbjfjdZzIaO9En/200w_s.gif?cid=ea1d2e62g20a2z6zrxsyk0fhlbomzsm3hni8gz7ppq4625qc&rid=200w_s.gif&ct=g",
"mp4_url": "",
"mp4_size": 0,
"webp_url": "",
"webp_size": 0
},
"fixed_width_downsampled": {
"height": 284,
"width": 200,
"size": 120572,
"url": "https://media2.giphy.com/media/gzBwhbjfjdZzIaO9En/200w_d.gif?cid=ea1d2e62g20a2z6zrxsyk0fhlbomzsm3hni8gz7ppq4625qc&rid=200w_d.gif&ct=g",
"mp4_url": "",
"mp4_size": 0,
"webp_url": "",
"webp_size": 79232
},
"fixed_height_small": {
"height": 100,
"width": 71,
"size": 52486,
"url": "https://media2.giphy.com/media/gzBwhbjfjdZzIaO9En/100.gif?cid=ea1d2e62g20a2z6zrxsyk0fhlbomzsm3hni8gz7ppq4625qc&rid=100.gif&ct=g",
"mp4_url": "",
"mp4_size": 29938,
"webp_url": "",
"webp_size": 31072
},
"fixed_height_small_still": {
"height": 100,
"width": 71,
"size": 4102,
"url": "https://media2.giphy.com/media/gzBwhbjfjdZzIaO9En/100_s.gif?cid=ea1d2e62g20a2z6zrxsyk0fhlbomzsm3hni8gz7ppq4625qc&rid=100_s.gif&ct=g",
"mp4_url": "",
"mp4_size": 0,
"webp_url": "",
"webp_size": 0
},
"fixed_width_small": {
"height": 142,
"width": 100,
"size": 91804,
"url": "https://media2.giphy.com/media/gzBwhbjfjdZzIaO9En/100w.gif?cid=ea1d2e62g20a2z6zrxsyk0fhlbomzsm3hni8gz7ppq4625qc&rid=100w.gif&ct=g",
"mp4_url": "",
"mp4_size": 50386,
"webp_url": "",
"webp_size": 54632
},
"fixed_width_small_still": {
"height": 142,
"width": 100,
"size": 6503,
"url": "https://media2.giphy.com/media/gzBwhbjfjdZzIaO9En/100w_s.gif?cid=ea1d2e62g20a2z6zrxsyk0fhlbomzsm3hni8gz7ppq4625qc&rid=100w_s.gif&ct=g",
"mp4_url": "",
"mp4_size": 0,
"webp_url": "",
"webp_size": 0
},
"downsized_still": {
"height": 480,
"width": 338,
"size": 726274,
"url": "https://media2.giphy.com/media/gzBwhbjfjdZzIaO9En/giphy_s.gif?cid=ea1d2e62g20a2z6zrxsyk0fhlbomzsm3hni8gz7ppq4625qc&rid=giphy_s.gif&ct=g",
"mp4_url": "",
"mp4_size": 0,
"webp_url": "",
"webp_size": 0
},
"downsized_large": {
"height": 480,
"width": 338,
"size": 726274,
"url": "https://media2.giphy.com/media/gzBwhbjfjdZzIaO9En/giphy.gif?cid=ea1d2e62g20a2z6zrxsyk0fhlbomzsm3hni8gz7ppq4625qc&rid=giphy.gif&ct=g",
"mp4_url": "",
"mp4_size": 0,
"webp_url": "",
"webp_size": 0
},
"downsized_medium": {
"height": 480,
"width": 338,
"size": 726274,
"url": "https://media2.giphy.com/media/gzBwhbjfjdZzIaO9En/giphy.gif?cid=ea1d2e62g20a2z6zrxsyk0fhlbomzsm3hni8gz7ppq4625qc&rid=giphy.gif&ct=g",
"mp4_url": "",
"mp4_size": 0,
"webp_url": "",
"webp_size": 0
},
"downsized_small": {
"height": 356,
"width": 250,
"size": 0,
"url": "",
"mp4_url": "",
"mp4_size": 150061,
"webp_url": "",
"webp_size": 0
},
"original_still": {
"height": 480,
"width": 338,
"size": 58197,
"url": "https://media2.giphy.com/media/gzBwhbjfjdZzIaO9En/giphy_s.gif?cid=ea1d2e62g20a2z6zrxsyk0fhlbomzsm3hni8gz7ppq4625qc&rid=giphy_s.gif&ct=g",
"mp4_url": "",
"mp4_size": 0,
"webp_url": "",
"webp_size": 0
},
"looping": {
"height": 0,
"width": 0,
"size": 0,
"url": "",
"mp4_url": "",
"mp4_size": 3811719,
"webp_url": "",
"webp_size": 0
},
"preview": {
"height": 150,
"width": 105,
"size": 0,
"url": "",
"mp4_url": "",
"mp4_size": 41991,
"webp_url": "",
"webp_size": 0
},
"preview_gif": {
"height": 87,
"width": 61,
"size": 49669,
"url": "https://media2.giphy.com/media/gzBwhbjfjdZzIaO9En/giphy-preview.gif?cid=ea1d2e62g20a2z6zrxsyk0fhlbomzsm3hni8gz7ppq4625qc&rid=giphy-preview.gif&ct=g",
"mp4_url": "",
"mp4_size": 0,
"webp_url": "",
"webp_size": 0
}
}
},
{
"id": "cLcxtL1z8t8oo",
"slug": "jump-training-rope-cLcxtL1z8t8oo",
"url": "https://giphy.com/gifs/jump-training-rope-cLcxtL1z8t8oo",
"short_url": "http://gph.is/1TEeoGs",
"embed_url": "https://giphy.com/embed/cLcxtL1z8t8oo",
"source": "https://www.reddit.com/r/gifs/comments/4itv7w/dogs_rope_jump_training_in_asia/",
"rating": "g",
"title": "Jump Dogs GIF",
"images": {
"original": {
"height": 352,
"width": 300,
"size": 3575754,
"url": "https://media2.giphy.com/media/cLcxtL1z8t8oo/giphy.gif?cid=ea1d2e62g20a2z6zrxsyk0fhlbomzsm3hni8gz7ppq4625qc&rid=giphy.gif&ct=g",
"mp4_url": "",
"mp4_size": 1968715,
"webp_url": "",
"webp_size": 1207266
},
"downsized": {
"height": 281,
"width": 240,
"size": 1475702,
"url": "https://media2.giphy.com/media/cLcxtL1z8t8oo/giphy-downsized.gif?cid=ea1d2e62g20a2z6zrxsyk0fhlbomzsm3hni8gz7ppq4625qc&rid=giphy-downsized.gif&ct=g",
"mp4_url": "",
"mp4_size": 0,
"webp_url": "",
"webp_size": 0
},
"fixed_height": {
"height": 200,
"width": 170,
"size": 923165,
"url": "https://media2.giphy.com/media/cLcxtL1z8t8oo/200.gif?cid=ea1d2e62g20a2z6zrxsyk0fhlbomzsm3hni8gz7ppq4625qc&rid=200.gif&ct=g",
"mp4_url": "",
"mp4_size": 245562,
"webp_url": "",
"webp_size": 377422
},
"fixed_height_still": {
"height": 200,
"width": 170,
"size": 16606,
"url": "https://media2.giphy.com/media/cLcxtL1z8t8oo/200_s.gif?cid=ea1d2e62g20a2z6zrxsyk0fhlbomzsm3hni8gz7ppq4625qc&rid=200_s.gif&ct=g",
"mp4_url": "",
"mp4_size": 0,
"webp_url": "",
"webp_size": 0
},
"fixed_height_downsampled": {
"height": 200,
"width": 170,
"size": 112472,
"url": "https://media2.giphy.com/media/cLcxtL1z8t8oo/200_d.gif?cid=ea1d2e62g20a2z6zrxsyk0fhlbomzsm3hni8gz7ppq4625qc&rid=200_d.gif&ct=g",
"mp4_url": "",
"mp4_size": 0,
"webp_url": "",
"webp_size": 64758
},
"fixed_width": {
"height": 235,
"width": 200,
"size": 1213931,
"url": "https://media2.giphy.com/media/cLcxtL1z8t8oo/200w.gif?cid=ea1d2e62g20a2z6zrxsyk0fhlbomzsm3hni8gz7ppq4625qc&rid=200w.gif&ct=g",
"mp4_url": "",
"mp4_size": 315433,
"webp_url": "",
"webp_size": 483128
},
"fixed_width_still": {
"height": 235,
"width": 200,
"size": 21560,
"url": "https://media2.giphy.com/media/cLcxtL1z8t8oo/200w_s.gif?cid=ea1d2e62g20a2z6zrxsyk0fhlbomzsm3hni8gz7ppq4625qc&rid=200w_s.gif&ct=g",
"mp4_url": "",
"mp4_size": 0,
"webp_url": "",
"webp_size": 0
},
"fixed_width_downsampled": {
"height": 235,
"width": 200,
"size": 147663,
"url": "https://media2.giphy.com/media/cLcxtL1z8t8oo/200w_d.gif?cid=ea1d2e62g20a2z6zrxsyk0fhlbomzsm3hni8gz7ppq4625qc&rid=200w_d.gif&ct=g",
"mp4_url": "",
"mp4_size": 0,
"webp_url": "",
"webp_size": 84616
},
"fixed_height_small": {
"height": 100,
"width": 85,
"size": 292401,
"url": "https://media2.giphy.com/media/cLcxtL1z8t8oo/100.gif?cid=ea1d2e62g20a2z6zrxsyk0fhlbomzsm3hni8gz7ppq4625qc&rid=100.gif&ct=g",
"mp4_url": "",
"mp4_size": 90135,
"webp_url": "",
"webp_size": 134976
},
"fixed_height_small_still": {
"height": 100,
"width": 85,
"size": 5747,
"url": "https://media2.giphy.com/media/cLcxtL1z8t8oo/100_s.gif?cid=ea1d2e62g20a2z6zrxsyk0fhlbomzsm3hni8gz7ppq4625qc&rid=100_s.gif&ct=g",
"mp4_url": "",
"mp4_size": 0,
"webp_url": "",
"webp_size": 0
},
"fixed_width_small": {
"height": 118,
"width": 100,
"size": 418819,
"url": "https://media2.giphy.com/media/cLcxtL1z8t8oo/100w.gif?cid=ea1d2e62g20a2z6zrxsyk0fhlbomzsm3hni8gz7ppq4625qc&rid=100w.gif&ct=g",
"mp4_url": "",
"mp4_size": 48616,
"webp_url": "",
"webp_size": 172170
},
"fixed_width_small_still": {
"height": 118,
"width": 100,
"size": 7841,
"url": "https://media2.giphy.com/media/cLcxtL1z8t8oo/100w_s.gif?cid=ea1d2e62g20a2z6zrxsyk0fhlbomzsm3hni8gz7ppq4625qc&rid=100w_s.gif&ct=g",
"mp4_url": "",
"mp4_size": 0,
"webp_url": "",
"webp_size": 0
},
"downsized_still": {
"height": 281,
"width": 240,
"size": 26226,
"url": "https://media2.giphy.com/media/cLcxtL1z8t8oo/giphy-downsized_s.gif?cid=ea1d2e62g20a2z6zrxsyk0fhlbomzsm3hni8gz7ppq4625qc&rid=giphy-downsized_s.gif&ct=g",
"mp4_url": "",
"mp4_size": 0,
"webp_url": "",
"webp_size": 0
},
"downsized_large": {
"height": 352,
"width": 300,
"size": 3575754,
"url": "https://media2.giphy.com/media/cLcxtL1z8t8oo/giphy.gif?cid=ea1d2e62g20a2z6zrxsyk0fhlbomzsm3hni8gz7ppq4625qc&rid=giphy.gif&ct=g",
"mp4_url": "",
"mp4_size": 0,
"webp_url": "",
"webp_size": 0
},
"downsized_medium": {
"height": 352,
"width": 300,
"size": 3575754,
"url": "https://media2.giphy.com/media/cLcxtL1z8t8oo/giphy.gif?cid=ea1d2e62g20a2z6zrxsyk0fhlbomzsm3hni8gz7ppq4625qc&rid=giphy.gif&ct=g",
"mp4_url": "",
"mp4_size": 0,
"webp_url": "",
"webp_size": 0
},
"downsized_small": {
"height": 152,
"width": 129,
"size": 0,
"url": "",
"mp4_url": "",
"mp4_size": 90680,
"webp_url": "",
"webp_size": 0
},
"original_still": {
"height": 352,
"width": 300,
"size": 62137,
"url": "https://media2.giphy.com/media/cLcxtL1z8t8oo/giphy_s.gif?cid=ea1d2e62g20a2z6zrxsyk0fhlbomzsm3hni8gz7ppq4625qc&rid=giphy_s.gif&ct=g",
"mp4_url": "",
"mp4_size": 0,
"webp_url": "",
"webp_size": 0
},
"looping": {
"height": 0,
"width": 0,
"size": 0,
"url": "",
"mp4_url": "",
"mp4_size": 5499938,
"webp_url": "",
"webp_size": 0
},
"preview": {
"height": 156,
"width": 132,
"size": 0,
"url": "",
"mp4_url": "",
"mp4_size": 44460,
"webp_url": "",
"webp_size": 0
},
"preview_gif": {
"height": 73,
"width": 62,
"size": 47597,
"url": "https://media2.giphy.com/media/cLcxtL1z8t8oo/giphy-preview.gif?cid=ea1d2e62g20a2z6zrxsyk0fhlbomzsm3hni8gz7ppq4625qc&rid=giphy-preview.gif&ct=g",
"mp4_url": "",
"mp4_size": 0,
"webp_url": "",
"webp_size": 0
}
}
}
],
"pagination": {
"offset": 0,
"total_count": 9735,
"count": 2
}
}
}
]
}

2
gifs/generate.go Normal file
View File

@@ -0,0 +1,2 @@
package main
//go:generate make proto

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"`
}

25
gifs/main.go Normal file
View File

@@ -0,0 +1,25 @@
package main
import (
"github.com/micro/services/gifs/handler"
pb "github.com/micro/services/gifs/proto"
"github.com/micro/micro/v3/service"
"github.com/micro/micro/v3/service/logger"
)
func main() {
// Create service
srv := service.New(
service.Name("gifs"),
service.Version("latest"),
)
// Register handler
pb.RegisterGifsHandler(srv.Server(), handler.New())
// Run service
if err := srv.Run(); err != nil {
logger.Fatal(err)
}
}

1
gifs/micro.mu Normal file
View File

@@ -0,0 +1 @@
service gifs

969
gifs/proto/gifs.pb.go Normal file
View File

@@ -0,0 +1,969 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.26.0
// protoc v3.15.5
// source: proto/gifs.proto
package gifs
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// Search for a gif
type SearchRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// The search term
Query string `protobuf:"bytes,1,opt,name=query,proto3" json:"query,omitempty"`
// Max number of gifs to return. Defaults to 25
Limit int32 `protobuf:"varint,2,opt,name=limit,proto3" json:"limit,omitempty"`
// The start position of results (used with pagination)
Offset int32 `protobuf:"varint,3,opt,name=offset,proto3" json:"offset,omitempty"`
// Apply age related content filter. "g", "pg", "pg-13", or "r". Defaults to "g"
Rating string `protobuf:"bytes,4,opt,name=rating,proto3" json:"rating,omitempty"`
// ISO 2 letter language code for regional content
Lang string `protobuf:"bytes,5,opt,name=lang,proto3" json:"lang,omitempty"`
}
func (x *SearchRequest) Reset() {
*x = SearchRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_gifs_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *SearchRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*SearchRequest) ProtoMessage() {}
func (x *SearchRequest) ProtoReflect() protoreflect.Message {
mi := &file_proto_gifs_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use SearchRequest.ProtoReflect.Descriptor instead.
func (*SearchRequest) Descriptor() ([]byte, []int) {
return file_proto_gifs_proto_rawDescGZIP(), []int{0}
}
func (x *SearchRequest) GetQuery() string {
if x != nil {
return x.Query
}
return ""
}
func (x *SearchRequest) GetLimit() int32 {
if x != nil {
return x.Limit
}
return 0
}
func (x *SearchRequest) GetOffset() int32 {
if x != nil {
return x.Offset
}
return 0
}
func (x *SearchRequest) GetRating() string {
if x != nil {
return x.Rating
}
return ""
}
func (x *SearchRequest) GetLang() string {
if x != nil {
return x.Lang
}
return ""
}
type SearchResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// list of results
Data []*Gif `protobuf:"bytes,1,rep,name=data,proto3" json:"data,omitempty"`
// information on pagination
Pagination *Pagination `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"`
}
func (x *SearchResponse) Reset() {
*x = SearchResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_gifs_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *SearchResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*SearchResponse) ProtoMessage() {}
func (x *SearchResponse) ProtoReflect() protoreflect.Message {
mi := &file_proto_gifs_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use SearchResponse.ProtoReflect.Descriptor instead.
func (*SearchResponse) Descriptor() ([]byte, []int) {
return file_proto_gifs_proto_rawDescGZIP(), []int{1}
}
func (x *SearchResponse) GetData() []*Gif {
if x != nil {
return x.Data
}
return nil
}
func (x *SearchResponse) GetPagination() *Pagination {
if x != nil {
return x.Pagination
}
return nil
}
type Pagination struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// position in pagination
Offset int32 `protobuf:"varint,1,opt,name=offset,proto3" json:"offset,omitempty"`
// total number of results available
TotalCount int32 `protobuf:"varint,2,opt,name=total_count,json=totalCount,proto3" json:"total_count,omitempty"`
// total number returned in this response
Count int32 `protobuf:"varint,3,opt,name=count,proto3" json:"count,omitempty"`
}
func (x *Pagination) Reset() {
*x = Pagination{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_gifs_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Pagination) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Pagination) ProtoMessage() {}
func (x *Pagination) ProtoReflect() protoreflect.Message {
mi := &file_proto_gifs_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Pagination.ProtoReflect.Descriptor instead.
func (*Pagination) Descriptor() ([]byte, []int) {
return file_proto_gifs_proto_rawDescGZIP(), []int{2}
}
func (x *Pagination) GetOffset() int32 {
if x != nil {
return x.Offset
}
return 0
}
func (x *Pagination) GetTotalCount() int32 {
if x != nil {
return x.TotalCount
}
return 0
}
func (x *Pagination) GetCount() int32 {
if x != nil {
return x.Count
}
return 0
}
type Gif struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// The ID of the GIF
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
// The slug used in the GIF's URL
Slug string `protobuf:"bytes,2,opt,name=slug,proto3" json:"slug,omitempty"`
// The URL for this GIF
Url string `protobuf:"bytes,3,opt,name=url,proto3" json:"url,omitempty"`
// A short URL for this GIF
ShortUrl string `protobuf:"bytes,4,opt,name=short_url,json=shortUrl,proto3" json:"short_url,omitempty"`
// URL used for embedding the GIF
EmbedUrl string `protobuf:"bytes,5,opt,name=embed_url,json=embedUrl,proto3" json:"embed_url,omitempty"`
// The page on which this GIF was found
Source string `protobuf:"bytes,6,opt,name=source,proto3" json:"source,omitempty"`
// The content rating for the GIF
Rating string `protobuf:"bytes,7,opt,name=rating,proto3" json:"rating,omitempty"`
// The title for this GIF
Title string `protobuf:"bytes,8,opt,name=title,proto3" json:"title,omitempty"`
// The different formats available for this GIF
Images *ImageFormats `protobuf:"bytes,9,opt,name=images,proto3" json:"images,omitempty"`
}
func (x *Gif) Reset() {
*x = Gif{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_gifs_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Gif) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Gif) ProtoMessage() {}
func (x *Gif) ProtoReflect() protoreflect.Message {
mi := &file_proto_gifs_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Gif.ProtoReflect.Descriptor instead.
func (*Gif) Descriptor() ([]byte, []int) {
return file_proto_gifs_proto_rawDescGZIP(), []int{3}
}
func (x *Gif) GetId() string {
if x != nil {
return x.Id
}
return ""
}
func (x *Gif) GetSlug() string {
if x != nil {
return x.Slug
}
return ""
}
func (x *Gif) GetUrl() string {
if x != nil {
return x.Url
}
return ""
}
func (x *Gif) GetShortUrl() string {
if x != nil {
return x.ShortUrl
}
return ""
}
func (x *Gif) GetEmbedUrl() string {
if x != nil {
return x.EmbedUrl
}
return ""
}
func (x *Gif) GetSource() string {
if x != nil {
return x.Source
}
return ""
}
func (x *Gif) GetRating() string {
if x != nil {
return x.Rating
}
return ""
}
func (x *Gif) GetTitle() string {
if x != nil {
return x.Title
}
return ""
}
func (x *Gif) GetImages() *ImageFormats {
if x != nil {
return x.Images
}
return nil
}
// A map of different formats (or renditions) of a GIF. See https://developers.giphy.com/docs/optional-settings#rendition-guide
type ImageFormats struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// The original GIF. Good for desktop use
Original *ImageFormat `protobuf:"bytes,1,opt,name=original,proto3" json:"original,omitempty"`
// A downsized version of the GIF < 2MB
Downsized *ImageFormat `protobuf:"bytes,2,opt,name=downsized,proto3" json:"downsized,omitempty"`
// Version of the GIF with fixed height of 200 pixels. Good for mobile use
FixedHeight *ImageFormat `protobuf:"bytes,3,opt,name=fixed_height,json=fixedHeight,proto3" json:"fixed_height,omitempty"`
// Static image of the GIF with fixed height of 200 pixels
FixedHeightStill *ImageFormat `protobuf:"bytes,4,opt,name=fixed_height_still,json=fixedHeightStill,proto3" json:"fixed_height_still,omitempty"`
// Version of the GIF with fixed height of 200 pixels and number of frames reduced to 6
FixedHeightDownsampled *ImageFormat `protobuf:"bytes,5,opt,name=fixed_height_downsampled,json=fixedHeightDownsampled,proto3" json:"fixed_height_downsampled,omitempty"`
// Version of the GIF with fixed width of 200 pixels. Good for mobile use
FixedWidth *ImageFormat `protobuf:"bytes,6,opt,name=fixed_width,json=fixedWidth,proto3" json:"fixed_width,omitempty"`
// Static image of the GIF with fixed width of 200 pixels
FixedWidthStill *ImageFormat `protobuf:"bytes,7,opt,name=fixed_width_still,json=fixedWidthStill,proto3" json:"fixed_width_still,omitempty"`
// Version of the GIF with fixed width of 200 pixels and number of frames reduced to 6
FixedWidthDownsampled *ImageFormat `protobuf:"bytes,8,opt,name=fixed_width_downsampled,json=fixedWidthDownsampled,proto3" json:"fixed_width_downsampled,omitempty"`
// Version of the GIF with fixed height of 100 pixels. Good for mobile keyboards
FixedHeightSmall *ImageFormat `protobuf:"bytes,9,opt,name=fixed_height_small,json=fixedHeightSmall,proto3" json:"fixed_height_small,omitempty"`
// Static image of the GIF with fixed height of 100 pixels
FixedHeightSmallStill *ImageFormat `protobuf:"bytes,10,opt,name=fixed_height_small_still,json=fixedHeightSmallStill,proto3" json:"fixed_height_small_still,omitempty"`
// Version of the GIF with fixed width of 100 pixels. Good for mobile keyboards
FixedWidthSmall *ImageFormat `protobuf:"bytes,11,opt,name=fixed_width_small,json=fixedWidthSmall,proto3" json:"fixed_width_small,omitempty"`
// Static image of the GIF with fixed width of 100 pixels
FixedWidthSmallStill *ImageFormat `protobuf:"bytes,12,opt,name=fixed_width_small_still,json=fixedWidthSmallStill,proto3" json:"fixed_width_small_still,omitempty"`
// Static image of the downsized version of the GIF
DownsizedStill *ImageFormat `protobuf:"bytes,13,opt,name=downsized_still,json=downsizedStill,proto3" json:"downsized_still,omitempty"`
// A downsized version of the GIF < 8MB
DownsizedLarge *ImageFormat `protobuf:"bytes,14,opt,name=downsized_large,json=downsizedLarge,proto3" json:"downsized_large,omitempty"`
// A downsized version of the GIF < 5MB
DownsizedMedium *ImageFormat `protobuf:"bytes,15,opt,name=downsized_medium,json=downsizedMedium,proto3" json:"downsized_medium,omitempty"`
// A downsized version of the GIF < 200kb
DownsizedSmall *ImageFormat `protobuf:"bytes,16,opt,name=downsized_small,json=downsizedSmall,proto3" json:"downsized_small,omitempty"`
// Static image of the original version of the GIF
OriginalStill *ImageFormat `protobuf:"bytes,17,opt,name=original_still,json=originalStill,proto3" json:"original_still,omitempty"`
// 15 second version of the GIF looping
Looping *ImageFormat `protobuf:"bytes,18,opt,name=looping,proto3" json:"looping,omitempty"`
// mp4 version of the GIF <50kb displaying first 1-2 secs
Preview *ImageFormat `protobuf:"bytes,19,opt,name=preview,proto3" json:"preview,omitempty"`
// Version of the GIF <50kb displaying first 1-2 secs
PreviewGif *ImageFormat `protobuf:"bytes,20,opt,name=preview_gif,json=previewGif,proto3" json:"preview_gif,omitempty"`
}
func (x *ImageFormats) Reset() {
*x = ImageFormats{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_gifs_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ImageFormats) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ImageFormats) ProtoMessage() {}
func (x *ImageFormats) ProtoReflect() protoreflect.Message {
mi := &file_proto_gifs_proto_msgTypes[4]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ImageFormats.ProtoReflect.Descriptor instead.
func (*ImageFormats) Descriptor() ([]byte, []int) {
return file_proto_gifs_proto_rawDescGZIP(), []int{4}
}
func (x *ImageFormats) GetOriginal() *ImageFormat {
if x != nil {
return x.Original
}
return nil
}
func (x *ImageFormats) GetDownsized() *ImageFormat {
if x != nil {
return x.Downsized
}
return nil
}
func (x *ImageFormats) GetFixedHeight() *ImageFormat {
if x != nil {
return x.FixedHeight
}
return nil
}
func (x *ImageFormats) GetFixedHeightStill() *ImageFormat {
if x != nil {
return x.FixedHeightStill
}
return nil
}
func (x *ImageFormats) GetFixedHeightDownsampled() *ImageFormat {
if x != nil {
return x.FixedHeightDownsampled
}
return nil
}
func (x *ImageFormats) GetFixedWidth() *ImageFormat {
if x != nil {
return x.FixedWidth
}
return nil
}
func (x *ImageFormats) GetFixedWidthStill() *ImageFormat {
if x != nil {
return x.FixedWidthStill
}
return nil
}
func (x *ImageFormats) GetFixedWidthDownsampled() *ImageFormat {
if x != nil {
return x.FixedWidthDownsampled
}
return nil
}
func (x *ImageFormats) GetFixedHeightSmall() *ImageFormat {
if x != nil {
return x.FixedHeightSmall
}
return nil
}
func (x *ImageFormats) GetFixedHeightSmallStill() *ImageFormat {
if x != nil {
return x.FixedHeightSmallStill
}
return nil
}
func (x *ImageFormats) GetFixedWidthSmall() *ImageFormat {
if x != nil {
return x.FixedWidthSmall
}
return nil
}
func (x *ImageFormats) GetFixedWidthSmallStill() *ImageFormat {
if x != nil {
return x.FixedWidthSmallStill
}
return nil
}
func (x *ImageFormats) GetDownsizedStill() *ImageFormat {
if x != nil {
return x.DownsizedStill
}
return nil
}
func (x *ImageFormats) GetDownsizedLarge() *ImageFormat {
if x != nil {
return x.DownsizedLarge
}
return nil
}
func (x *ImageFormats) GetDownsizedMedium() *ImageFormat {
if x != nil {
return x.DownsizedMedium
}
return nil
}
func (x *ImageFormats) GetDownsizedSmall() *ImageFormat {
if x != nil {
return x.DownsizedSmall
}
return nil
}
func (x *ImageFormats) GetOriginalStill() *ImageFormat {
if x != nil {
return x.OriginalStill
}
return nil
}
func (x *ImageFormats) GetLooping() *ImageFormat {
if x != nil {
return x.Looping
}
return nil
}
func (x *ImageFormats) GetPreview() *ImageFormat {
if x != nil {
return x.Preview
}
return nil
}
func (x *ImageFormats) GetPreviewGif() *ImageFormat {
if x != nil {
return x.PreviewGif
}
return nil
}
type ImageFormat struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// height
Height int32 `protobuf:"varint,1,opt,name=height,proto3" json:"height,omitempty"`
// width
Width int32 `protobuf:"varint,2,opt,name=width,proto3" json:"width,omitempty"`
// size in bytes
Size int32 `protobuf:"varint,3,opt,name=size,proto3" json:"size,omitempty"`
// URL of the gif
Url string `protobuf:"bytes,4,opt,name=url,proto3" json:"url,omitempty"`
// URL to an MP4 version of the gif
Mp4Url string `protobuf:"bytes,5,opt,name=mp4_url,json=mp4Url,proto3" json:"mp4_url,omitempty"`
// size of the MP4 version
Mp4Size int32 `protobuf:"varint,6,opt,name=mp4_size,json=mp4Size,proto3" json:"mp4_size,omitempty"`
// URL to a webp version of the gif
WebpUrl string `protobuf:"bytes,7,opt,name=webp_url,json=webpUrl,proto3" json:"webp_url,omitempty"`
// size of the webp version
WebpSize int32 `protobuf:"varint,8,opt,name=webp_size,json=webpSize,proto3" json:"webp_size,omitempty"`
}
func (x *ImageFormat) Reset() {
*x = ImageFormat{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_gifs_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ImageFormat) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ImageFormat) ProtoMessage() {}
func (x *ImageFormat) ProtoReflect() protoreflect.Message {
mi := &file_proto_gifs_proto_msgTypes[5]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ImageFormat.ProtoReflect.Descriptor instead.
func (*ImageFormat) Descriptor() ([]byte, []int) {
return file_proto_gifs_proto_rawDescGZIP(), []int{5}
}
func (x *ImageFormat) GetHeight() int32 {
if x != nil {
return x.Height
}
return 0
}
func (x *ImageFormat) GetWidth() int32 {
if x != nil {
return x.Width
}
return 0
}
func (x *ImageFormat) GetSize() int32 {
if x != nil {
return x.Size
}
return 0
}
func (x *ImageFormat) GetUrl() string {
if x != nil {
return x.Url
}
return ""
}
func (x *ImageFormat) GetMp4Url() string {
if x != nil {
return x.Mp4Url
}
return ""
}
func (x *ImageFormat) GetMp4Size() int32 {
if x != nil {
return x.Mp4Size
}
return 0
}
func (x *ImageFormat) GetWebpUrl() string {
if x != nil {
return x.WebpUrl
}
return ""
}
func (x *ImageFormat) GetWebpSize() int32 {
if x != nil {
return x.WebpSize
}
return 0
}
var File_proto_gifs_proto protoreflect.FileDescriptor
var file_proto_gifs_proto_rawDesc = []byte{
0x0a, 0x10, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x69, 0x66, 0x73, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x12, 0x04, 0x67, 0x69, 0x66, 0x73, 0x22, 0x7f, 0x0a, 0x0d, 0x53, 0x65, 0x61, 0x72,
0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65,
0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12,
0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05,
0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18,
0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x16, 0x0a,
0x06, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72,
0x61, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x18, 0x05, 0x20,
0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x22, 0x61, 0x0a, 0x0e, 0x53, 0x65, 0x61,
0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x04, 0x64,
0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x67, 0x69, 0x66, 0x73,
0x2e, 0x47, 0x69, 0x66, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x30, 0x0a, 0x0a, 0x70, 0x61,
0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10,
0x2e, 0x67, 0x69, 0x66, 0x73, 0x2e, 0x50, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x5b, 0x0a, 0x0a,
0x50, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66,
0x66, 0x73, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73,
0x65, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x63, 0x6f, 0x75, 0x6e,
0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x43, 0x6f,
0x75, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01,
0x28, 0x05, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xe7, 0x01, 0x0a, 0x03, 0x47, 0x69,
0x66, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69,
0x64, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x6c, 0x75, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
0x04, 0x73, 0x6c, 0x75, 0x67, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01,
0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x68, 0x6f, 0x72, 0x74,
0x5f, 0x75, 0x72, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x68, 0x6f, 0x72,
0x74, 0x55, 0x72, 0x6c, 0x12, 0x1b, 0x0a, 0x09, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x5f, 0x75, 0x72,
0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x55, 0x72,
0x6c, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28,
0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x61, 0x74,
0x69, 0x6e, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x61, 0x74, 0x69, 0x6e,
0x67, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09,
0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x69, 0x6d, 0x61, 0x67, 0x65,
0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x66, 0x73, 0x2e, 0x49,
0x6d, 0x61, 0x67, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x73, 0x52, 0x06, 0x69, 0x6d, 0x61,
0x67, 0x65, 0x73, 0x22, 0xc0, 0x09, 0x0a, 0x0c, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x46, 0x6f, 0x72,
0x6d, 0x61, 0x74, 0x73, 0x12, 0x2d, 0x0a, 0x08, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c,
0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x67, 0x69, 0x66, 0x73, 0x2e, 0x49, 0x6d,
0x61, 0x67, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x08, 0x6f, 0x72, 0x69, 0x67, 0x69,
0x6e, 0x61, 0x6c, 0x12, 0x2f, 0x0a, 0x09, 0x64, 0x6f, 0x77, 0x6e, 0x73, 0x69, 0x7a, 0x65, 0x64,
0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x67, 0x69, 0x66, 0x73, 0x2e, 0x49, 0x6d,
0x61, 0x67, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x09, 0x64, 0x6f, 0x77, 0x6e, 0x73,
0x69, 0x7a, 0x65, 0x64, 0x12, 0x34, 0x0a, 0x0c, 0x66, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x68, 0x65,
0x69, 0x67, 0x68, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x67, 0x69, 0x66,
0x73, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x0b, 0x66,
0x69, 0x78, 0x65, 0x64, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x3f, 0x0a, 0x12, 0x66, 0x69,
0x78, 0x65, 0x64, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x73, 0x74, 0x69, 0x6c, 0x6c,
0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x67, 0x69, 0x66, 0x73, 0x2e, 0x49, 0x6d,
0x61, 0x67, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x10, 0x66, 0x69, 0x78, 0x65, 0x64,
0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x53, 0x74, 0x69, 0x6c, 0x6c, 0x12, 0x4b, 0x0a, 0x18, 0x66,
0x69, 0x78, 0x65, 0x64, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x64, 0x6f, 0x77, 0x6e,
0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e,
0x67, 0x69, 0x66, 0x73, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74,
0x52, 0x16, 0x66, 0x69, 0x78, 0x65, 0x64, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x44, 0x6f, 0x77,
0x6e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x64, 0x12, 0x32, 0x0a, 0x0b, 0x66, 0x69, 0x78, 0x65,
0x64, 0x5f, 0x77, 0x69, 0x64, 0x74, 0x68, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e,
0x67, 0x69, 0x66, 0x73, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74,
0x52, 0x0a, 0x66, 0x69, 0x78, 0x65, 0x64, 0x57, 0x69, 0x64, 0x74, 0x68, 0x12, 0x3d, 0x0a, 0x11,
0x66, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x77, 0x69, 0x64, 0x74, 0x68, 0x5f, 0x73, 0x74, 0x69, 0x6c,
0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x67, 0x69, 0x66, 0x73, 0x2e, 0x49,
0x6d, 0x61, 0x67, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x0f, 0x66, 0x69, 0x78, 0x65,
0x64, 0x57, 0x69, 0x64, 0x74, 0x68, 0x53, 0x74, 0x69, 0x6c, 0x6c, 0x12, 0x49, 0x0a, 0x17, 0x66,
0x69, 0x78, 0x65, 0x64, 0x5f, 0x77, 0x69, 0x64, 0x74, 0x68, 0x5f, 0x64, 0x6f, 0x77, 0x6e, 0x73,
0x61, 0x6d, 0x70, 0x6c, 0x65, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x67,
0x69, 0x66, 0x73, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52,
0x15, 0x66, 0x69, 0x78, 0x65, 0x64, 0x57, 0x69, 0x64, 0x74, 0x68, 0x44, 0x6f, 0x77, 0x6e, 0x73,
0x61, 0x6d, 0x70, 0x6c, 0x65, 0x64, 0x12, 0x3f, 0x0a, 0x12, 0x66, 0x69, 0x78, 0x65, 0x64, 0x5f,
0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x18, 0x09, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x11, 0x2e, 0x67, 0x69, 0x66, 0x73, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x46,
0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x10, 0x66, 0x69, 0x78, 0x65, 0x64, 0x48, 0x65, 0x69, 0x67,
0x68, 0x74, 0x53, 0x6d, 0x61, 0x6c, 0x6c, 0x12, 0x4a, 0x0a, 0x18, 0x66, 0x69, 0x78, 0x65, 0x64,
0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x5f, 0x73, 0x74,
0x69, 0x6c, 0x6c, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x67, 0x69, 0x66, 0x73,
0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x15, 0x66, 0x69,
0x78, 0x65, 0x64, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x53, 0x6d, 0x61, 0x6c, 0x6c, 0x53, 0x74,
0x69, 0x6c, 0x6c, 0x12, 0x3d, 0x0a, 0x11, 0x66, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x77, 0x69, 0x64,
0x74, 0x68, 0x5f, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11,
0x2e, 0x67, 0x69, 0x66, 0x73, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61,
0x74, 0x52, 0x0f, 0x66, 0x69, 0x78, 0x65, 0x64, 0x57, 0x69, 0x64, 0x74, 0x68, 0x53, 0x6d, 0x61,
0x6c, 0x6c, 0x12, 0x48, 0x0a, 0x17, 0x66, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x77, 0x69, 0x64, 0x74,
0x68, 0x5f, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x5f, 0x73, 0x74, 0x69, 0x6c, 0x6c, 0x18, 0x0c, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x67, 0x69, 0x66, 0x73, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65,
0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x14, 0x66, 0x69, 0x78, 0x65, 0x64, 0x57, 0x69, 0x64,
0x74, 0x68, 0x53, 0x6d, 0x61, 0x6c, 0x6c, 0x53, 0x74, 0x69, 0x6c, 0x6c, 0x12, 0x3a, 0x0a, 0x0f,
0x64, 0x6f, 0x77, 0x6e, 0x73, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x73, 0x74, 0x69, 0x6c, 0x6c, 0x18,
0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x67, 0x69, 0x66, 0x73, 0x2e, 0x49, 0x6d, 0x61,
0x67, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x0e, 0x64, 0x6f, 0x77, 0x6e, 0x73, 0x69,
0x7a, 0x65, 0x64, 0x53, 0x74, 0x69, 0x6c, 0x6c, 0x12, 0x3a, 0x0a, 0x0f, 0x64, 0x6f, 0x77, 0x6e,
0x73, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x6c, 0x61, 0x72, 0x67, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x11, 0x2e, 0x67, 0x69, 0x66, 0x73, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x46, 0x6f,
0x72, 0x6d, 0x61, 0x74, 0x52, 0x0e, 0x64, 0x6f, 0x77, 0x6e, 0x73, 0x69, 0x7a, 0x65, 0x64, 0x4c,
0x61, 0x72, 0x67, 0x65, 0x12, 0x3c, 0x0a, 0x10, 0x64, 0x6f, 0x77, 0x6e, 0x73, 0x69, 0x7a, 0x65,
0x64, 0x5f, 0x6d, 0x65, 0x64, 0x69, 0x75, 0x6d, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11,
0x2e, 0x67, 0x69, 0x66, 0x73, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61,
0x74, 0x52, 0x0f, 0x64, 0x6f, 0x77, 0x6e, 0x73, 0x69, 0x7a, 0x65, 0x64, 0x4d, 0x65, 0x64, 0x69,
0x75, 0x6d, 0x12, 0x3a, 0x0a, 0x0f, 0x64, 0x6f, 0x77, 0x6e, 0x73, 0x69, 0x7a, 0x65, 0x64, 0x5f,
0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x67, 0x69,
0x66, 0x73, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x0e,
0x64, 0x6f, 0x77, 0x6e, 0x73, 0x69, 0x7a, 0x65, 0x64, 0x53, 0x6d, 0x61, 0x6c, 0x6c, 0x12, 0x38,
0x0a, 0x0e, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x5f, 0x73, 0x74, 0x69, 0x6c, 0x6c,
0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x67, 0x69, 0x66, 0x73, 0x2e, 0x49, 0x6d,
0x61, 0x67, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x0d, 0x6f, 0x72, 0x69, 0x67, 0x69,
0x6e, 0x61, 0x6c, 0x53, 0x74, 0x69, 0x6c, 0x6c, 0x12, 0x2b, 0x0a, 0x07, 0x6c, 0x6f, 0x6f, 0x70,
0x69, 0x6e, 0x67, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x67, 0x69, 0x66, 0x73,
0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x07, 0x6c, 0x6f,
0x6f, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x2b, 0x0a, 0x07, 0x70, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77,
0x18, 0x13, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x67, 0x69, 0x66, 0x73, 0x2e, 0x49, 0x6d,
0x61, 0x67, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x07, 0x70, 0x72, 0x65, 0x76, 0x69,
0x65, 0x77, 0x12, 0x32, 0x0a, 0x0b, 0x70, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x5f, 0x67, 0x69,
0x66, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x67, 0x69, 0x66, 0x73, 0x2e, 0x49,
0x6d, 0x61, 0x67, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x0a, 0x70, 0x72, 0x65, 0x76,
0x69, 0x65, 0x77, 0x47, 0x69, 0x66, 0x22, 0xcd, 0x01, 0x0a, 0x0b, 0x49, 0x6d, 0x61, 0x67, 0x65,
0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74,
0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x14,
0x0a, 0x05, 0x77, 0x69, 0x64, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x77,
0x69, 0x64, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01,
0x28, 0x05, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18,
0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x17, 0x0a, 0x07, 0x6d, 0x70,
0x34, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x70, 0x34,
0x55, 0x72, 0x6c, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x70, 0x34, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18,
0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x6d, 0x70, 0x34, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x19,
0x0a, 0x08, 0x77, 0x65, 0x62, 0x70, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09,
0x52, 0x07, 0x77, 0x65, 0x62, 0x70, 0x55, 0x72, 0x6c, 0x12, 0x1b, 0x0a, 0x09, 0x77, 0x65, 0x62,
0x70, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x77, 0x65,
0x62, 0x70, 0x53, 0x69, 0x7a, 0x65, 0x32, 0x3d, 0x0a, 0x04, 0x47, 0x69, 0x66, 0x73, 0x12, 0x35,
0x0a, 0x06, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x12, 0x13, 0x2e, 0x67, 0x69, 0x66, 0x73, 0x2e,
0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e,
0x67, 0x69, 0x66, 0x73, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x0e, 0x5a, 0x0c, 0x2e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x3b, 0x67, 0x69, 0x66, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_proto_gifs_proto_rawDescOnce sync.Once
file_proto_gifs_proto_rawDescData = file_proto_gifs_proto_rawDesc
)
func file_proto_gifs_proto_rawDescGZIP() []byte {
file_proto_gifs_proto_rawDescOnce.Do(func() {
file_proto_gifs_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_gifs_proto_rawDescData)
})
return file_proto_gifs_proto_rawDescData
}
var file_proto_gifs_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
var file_proto_gifs_proto_goTypes = []interface{}{
(*SearchRequest)(nil), // 0: gifs.SearchRequest
(*SearchResponse)(nil), // 1: gifs.SearchResponse
(*Pagination)(nil), // 2: gifs.Pagination
(*Gif)(nil), // 3: gifs.Gif
(*ImageFormats)(nil), // 4: gifs.ImageFormats
(*ImageFormat)(nil), // 5: gifs.ImageFormat
}
var file_proto_gifs_proto_depIdxs = []int32{
3, // 0: gifs.SearchResponse.data:type_name -> gifs.Gif
2, // 1: gifs.SearchResponse.pagination:type_name -> gifs.Pagination
4, // 2: gifs.Gif.images:type_name -> gifs.ImageFormats
5, // 3: gifs.ImageFormats.original:type_name -> gifs.ImageFormat
5, // 4: gifs.ImageFormats.downsized:type_name -> gifs.ImageFormat
5, // 5: gifs.ImageFormats.fixed_height:type_name -> gifs.ImageFormat
5, // 6: gifs.ImageFormats.fixed_height_still:type_name -> gifs.ImageFormat
5, // 7: gifs.ImageFormats.fixed_height_downsampled:type_name -> gifs.ImageFormat
5, // 8: gifs.ImageFormats.fixed_width:type_name -> gifs.ImageFormat
5, // 9: gifs.ImageFormats.fixed_width_still:type_name -> gifs.ImageFormat
5, // 10: gifs.ImageFormats.fixed_width_downsampled:type_name -> gifs.ImageFormat
5, // 11: gifs.ImageFormats.fixed_height_small:type_name -> gifs.ImageFormat
5, // 12: gifs.ImageFormats.fixed_height_small_still:type_name -> gifs.ImageFormat
5, // 13: gifs.ImageFormats.fixed_width_small:type_name -> gifs.ImageFormat
5, // 14: gifs.ImageFormats.fixed_width_small_still:type_name -> gifs.ImageFormat
5, // 15: gifs.ImageFormats.downsized_still:type_name -> gifs.ImageFormat
5, // 16: gifs.ImageFormats.downsized_large:type_name -> gifs.ImageFormat
5, // 17: gifs.ImageFormats.downsized_medium:type_name -> gifs.ImageFormat
5, // 18: gifs.ImageFormats.downsized_small:type_name -> gifs.ImageFormat
5, // 19: gifs.ImageFormats.original_still:type_name -> gifs.ImageFormat
5, // 20: gifs.ImageFormats.looping:type_name -> gifs.ImageFormat
5, // 21: gifs.ImageFormats.preview:type_name -> gifs.ImageFormat
5, // 22: gifs.ImageFormats.preview_gif:type_name -> gifs.ImageFormat
0, // 23: gifs.Gifs.Search:input_type -> gifs.SearchRequest
1, // 24: gifs.Gifs.Search:output_type -> gifs.SearchResponse
24, // [24:25] is the sub-list for method output_type
23, // [23:24] is the sub-list for method input_type
23, // [23:23] is the sub-list for extension type_name
23, // [23:23] is the sub-list for extension extendee
0, // [0:23] is the sub-list for field type_name
}
func init() { file_proto_gifs_proto_init() }
func file_proto_gifs_proto_init() {
if File_proto_gifs_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_proto_gifs_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*SearchRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_proto_gifs_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*SearchResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_proto_gifs_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Pagination); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_proto_gifs_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Gif); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_proto_gifs_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ImageFormats); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_proto_gifs_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ImageFormat); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_proto_gifs_proto_rawDesc,
NumEnums: 0,
NumMessages: 6,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_proto_gifs_proto_goTypes,
DependencyIndexes: file_proto_gifs_proto_depIdxs,
MessageInfos: file_proto_gifs_proto_msgTypes,
}.Build()
File_proto_gifs_proto = out.File
file_proto_gifs_proto_rawDesc = nil
file_proto_gifs_proto_goTypes = nil
file_proto_gifs_proto_depIdxs = nil
}

View File

@@ -0,0 +1,93 @@
// Code generated by protoc-gen-micro. DO NOT EDIT.
// source: proto/gifs.proto
package gifs
import (
fmt "fmt"
proto "github.com/golang/protobuf/proto"
math "math"
)
import (
context "context"
api "github.com/micro/micro/v3/service/api"
client "github.com/micro/micro/v3/service/client"
server "github.com/micro/micro/v3/service/server"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
// Reference imports to suppress errors if they are not otherwise used.
var _ api.Endpoint
var _ context.Context
var _ client.Option
var _ server.Option
// Api Endpoints for Gifs service
func NewGifsEndpoints() []*api.Endpoint {
return []*api.Endpoint{}
}
// Client API for Gifs service
type GifsService interface {
Search(ctx context.Context, in *SearchRequest, opts ...client.CallOption) (*SearchResponse, error)
}
type gifsService struct {
c client.Client
name string
}
func NewGifsService(name string, c client.Client) GifsService {
return &gifsService{
c: c,
name: name,
}
}
func (c *gifsService) Search(ctx context.Context, in *SearchRequest, opts ...client.CallOption) (*SearchResponse, error) {
req := c.c.NewRequest(c.name, "Gifs.Search", in)
out := new(SearchResponse)
err := c.c.Call(ctx, req, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// Server API for Gifs service
type GifsHandler interface {
Search(context.Context, *SearchRequest, *SearchResponse) error
}
func RegisterGifsHandler(s server.Server, hdlr GifsHandler, opts ...server.HandlerOption) error {
type gifs interface {
Search(ctx context.Context, in *SearchRequest, out *SearchResponse) error
}
type Gifs struct {
gifs
}
h := &gifsHandler{hdlr}
return s.Handle(s.NewHandler(&Gifs{h}, opts...))
}
type gifsHandler struct {
GifsHandler
}
func (h *gifsHandler) Search(ctx context.Context, in *SearchRequest, out *SearchResponse) error {
return h.GifsHandler.Search(ctx, in, out)
}

126
gifs/proto/gifs.proto Normal file
View File

@@ -0,0 +1,126 @@
syntax = "proto3";
package gifs;
option go_package = "./proto;gifs";
service Gifs {
rpc Search(SearchRequest) returns (SearchResponse) {}
}
// Search for a gif
message SearchRequest {
// The search term
string query = 1;
// Max number of gifs to return. Defaults to 25
int32 limit = 2;
// The start position of results (used with pagination)
int32 offset = 3;
// Apply age related content filter. "g", "pg", "pg-13", or "r". Defaults to "g"
string rating = 4;
// ISO 2 letter language code for regional content
string lang = 5;
}
message SearchResponse {
// list of results
repeated Gif data = 1;
// information on pagination
Pagination pagination = 2;
}
message Pagination {
// position in pagination
int32 offset = 1;
// total number of results available
int32 total_count = 2;
// total number returned in this response
int32 count = 3;
}
message Gif {
// The ID of the GIF
string id = 1;
// The slug used in the GIF's URL
string slug = 2;
// The URL for this GIF
string url = 3;
// A short URL for this GIF
string short_url = 4;
// URL used for embedding the GIF
string embed_url = 5;
// The page on which this GIF was found
string source = 6;
// The content rating for the GIF
string rating = 7;
// The title for this GIF
string title = 8;
// The different formats available for this GIF
ImageFormats images = 9;
}
// A map of different formats (or renditions) of a GIF. See https://developers.giphy.com/docs/optional-settings#rendition-guide
message ImageFormats {
// The original GIF. Good for desktop use
ImageFormat original = 1;
// A downsized version of the GIF < 2MB
ImageFormat downsized = 2;
// Version of the GIF with fixed height of 200 pixels. Good for mobile use
ImageFormat fixed_height = 3;
// Static image of the GIF with fixed height of 200 pixels
ImageFormat fixed_height_still = 4;
// Version of the GIF with fixed height of 200 pixels and number of frames reduced to 6
ImageFormat fixed_height_downsampled = 5;
// Version of the GIF with fixed width of 200 pixels. Good for mobile use
ImageFormat fixed_width = 6;
// Static image of the GIF with fixed width of 200 pixels
ImageFormat fixed_width_still = 7;
// Version of the GIF with fixed width of 200 pixels and number of frames reduced to 6
ImageFormat fixed_width_downsampled = 8;
// Version of the GIF with fixed height of 100 pixels. Good for mobile keyboards
ImageFormat fixed_height_small = 9;
// Static image of the GIF with fixed height of 100 pixels
ImageFormat fixed_height_small_still = 10;
// Version of the GIF with fixed width of 100 pixels. Good for mobile keyboards
ImageFormat fixed_width_small = 11;
// Static image of the GIF with fixed width of 100 pixels
ImageFormat fixed_width_small_still = 12;
// Static image of the downsized version of the GIF
ImageFormat downsized_still = 13;
// A downsized version of the GIF < 8MB
ImageFormat downsized_large = 14;
// A downsized version of the GIF < 5MB
ImageFormat downsized_medium = 15;
// A downsized version of the GIF < 200kb
ImageFormat downsized_small = 16;
// Static image of the original version of the GIF
ImageFormat original_still = 17;
// 15 second version of the GIF looping
ImageFormat looping = 18;
// mp4 version of the GIF <50kb displaying first 1-2 secs
ImageFormat preview = 19;
// Version of the GIF <50kb displaying first 1-2 secs
ImageFormat preview_gif = 20;
}
message ImageFormat {
// height
int32 height = 1;
// width
int32 width = 2;
// size in bytes
int32 size = 3;
// URL of the gif
string url = 4;
// URL to an MP4 version of the gif
string mp4_url = 5;
// size of the MP4 version
int32 mp4_size = 6;
// URL to a webp version of the gif
string webp_url = 7;
// size of the webp version
int32 webp_size = 8;
}

5
gifs/publicapi.json Normal file
View File

@@ -0,0 +1,5 @@
{
"name": "gifs",
"icon": "🎥",
"category": "web"
}