-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbetafaceapi.go
222 lines (188 loc) · 7.48 KB
/
betafaceapi.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
package gobetafaceapi
import (
"encoding/json"
"fmt"
"strings"
"github.com/enriquebris/gohttpclient"
)
// ************************************************************************************************
// ** Betaface interface
// ************************************************************************************************
// Betafaceapi methods
type Betafaceapi interface {
// HTTPClient methods
getHTTPClient() gohttpclient.HTTPClient
setHTTPClient(httpClient gohttpclient.HTTPClient)
// GetMedia methods
setGetMediaEndpointURL(url string)
GetMedia(mediaUUID string) (gohttpclient.HTTPResponse, *Media, ErrorResponse, error)
// SendMedia methods
setSendMediaEndpointURL(url string)
SendMedia(fileURI string, flags DetectionFlags, recognizeTargets []string, originalFilename string) (gohttpclient.HTTPResponse, *ExtendedMedia, ErrorResponse, error)
//SendPerson(facesUUIDs []string, personID string)
}
// ************************************************************************************************
// ** NativeHTTPClient == (Betafaceapi + NativeHTTPClient) implementation
// ************************************************************************************************
// NewNativeHTTPClient builds and returns a *BasicClient using a NewNativeHTTPClient as HTTPClient (Implementor, Bridge pattern)
func NewNativeHTTPClient(apiKey string, apiSecret string) *BasicClient {
ret := &BasicClient{}
ret.initialize(apiKey, apiSecret)
ret.setHTTPClient(gohttpclient.NewNativeHTTPClient())
return ret
}
// ************************************************************************************************
// ** BasicClient == Basic Betafaceapi client. This class implements Betafaceapi interface.
// ************************************************************************************************
// BasicClient is a basic implementation of Betafaceapi interface.
// It does not contain a HTTPClient (Implementor for the Bridge pattern).
// It is the Abstractor (Bridge pattern)
type BasicClient struct {
apiKey string
apiSecret string
httpClient gohttpclient.HTTPClient
// endpoints URL
getMediaURL string
sendMediaURL string
}
// initialize initializes the BasicClient class
func (st *BasicClient) initialize(apiKey string, apiSecret string) {
st.apiKey = apiKey
st.apiSecret = apiSecret
// endpoints
st.setGetMediaEndpointURL(GetMediaEndpoint)
st.setSendMediaEndpointURL(SendMediaEndpoint)
}
// checkHTTPClient checks whether the HTTPClient was provided and return error if it was not
func (st *BasicClient) checkHTTPClient() error {
if st.httpClient == nil {
return NewError(ErrorCodeNotImplemented, "Missing Implementor (HTTPClient) to complete the Bridge pattern")
}
return nil
}
// getHTTPClient returns the HTTPClient (the Implementor for the Bridge pattern)
func (st *BasicClient) getHTTPClient() gohttpclient.HTTPClient {
return st.httpClient
}
// setHTTPClient sets the HTTPClient (the Implementor for the Bridge pattern)
func (st *BasicClient) setHTTPClient(httpClient gohttpclient.HTTPClient) {
st.httpClient = httpClient
}
// setGetMediaEndpointURL sets the GetMedia endpoint URL
func (st *BasicClient) setGetMediaEndpointURL(url string) {
st.getMediaURL = url
}
// getGetMediaEndpointURL returns the GetMedia final endpoint URL (based on the given parameters: apiKey and mediaUUID)
func (st *BasicClient) getGetMediaEndpointURL(apiKey string, mediaUUID string) string {
return fmt.Sprintf(st.getMediaURL, apiKey, mediaUUID)
}
// GetMedia gets and returns media information
// Possible responses (HTTP status code):
// 200 ==> the media resource was successfully retrieved. Media data comes into *Media
// 400 ==> bad request (invalid mediaUUID). Only gohttpclient.HTTPResponse contains data, no media data or error is provided.
// 404 ==> the media does not exist
// 500 ==> server error. Error info comes into ErrorResponse
// For all above cases, the HTTP response comes into HTTPResponse
//
// Endpoint: [GET] /v2/media
func (st *BasicClient) GetMedia(mediaUUID string) (gohttpclient.HTTPResponse, *Media, ErrorResponse, error) {
// verifies that this class contains an implementor (HTTPClient)
if err := st.checkHTTPClient(); err != nil {
return nil, nil, ErrorResponse{}, err
}
// verifies that the mediaUUID is not an empty string
if strings.TrimSpace(mediaUUID) == "" {
return nil, nil, ErrorResponse{}, NewError(ErrorCodeArguments, "mediaUUID can't be an empty string")
}
// querystring
url := st.getGetMediaEndpointURL(st.apiKey, mediaUUID)
// build the http request
st.getHTTPClient().Reset()
st.getHTTPClient().SetMethod(GetMediaMethod)
st.getHTTPClient().SetURL(url)
st.getHTTPClient().AddHeader("Content-Type", "application/json")
// send the request
resp, err := st.getHTTPClient().Do()
if err != nil {
return nil, nil, ErrorResponse{}, NewError(ErrorCodeHTTPRequest, err.Error())
}
// decode json based on the http response status
var (
mediaResp Media
ptrMediaResp *Media = nil
mediaError ErrorResponse
)
switch resp.GetStatusCode() {
case 200:
err = json.Unmarshal([]byte(resp.GetBody()), &mediaResp)
ptrMediaResp = &mediaResp
case 400:
case 404:
case 500:
err = json.Unmarshal([]byte(resp.GetBody()), &mediaError)
default:
}
// verify possible unmarshal error
if err != nil {
return resp, nil, ErrorResponse{}, NewError(ErrorCodeJSONUnmarshal, err.Error())
}
return resp, ptrMediaResp, mediaError, nil
}
// setSendMediaEndpointURL sets the SendMedia endpoint URL
func (st *BasicClient) setSendMediaEndpointURL(url string) {
st.sendMediaURL = url
}
// SendMedia uploads media file using file URI or file content as BASE64 encoded string.
// Note: all recognizeTargets have to be previously registered, otherwise the API would return error 500.
// Endpoint: [POST] /v2/media
func (st *BasicClient) SendMedia(fileURI string, flags DetectionFlags, recognizeTargets []string, originalFilename string) (gohttpclient.HTTPResponse, *ExtendedMedia, ErrorResponse, error) {
// verifies that this class contains an implementor (HTTPClient)
if err := st.checkHTTPClient(); err != nil {
return nil, nil, ErrorResponse{}, err
}
// build the payload object
payload := SendMediaRequest{
ApiKey: st.apiKey,
FileURI: fileURI,
OriginalFilename: originalFilename,
DetectionFlags: flags.String(),
RecognizeTargets: recognizeTargets,
}
// json payload
payloadJSON, err := json.Marshal(&payload)
if err != nil {
return nil, nil, ErrorResponse{}, NewError(ErrorCodeJSONMarshal, err.Error())
}
// build the http request
st.getHTTPClient().Reset()
st.getHTTPClient().SetMethod(SendMediaMethod)
st.getHTTPClient().SetURL(st.sendMediaURL)
st.getHTTPClient().AddHeader("Content-Type", "application/json")
st.getHTTPClient().SetPayload(string(payloadJSON))
// send the request
resp, err := st.getHTTPClient().Do()
if err != nil {
return nil, nil, ErrorResponse{}, NewError(ErrorCodeHTTPRequest, err.Error())
}
// decode json based on the http response status
var (
sendMediaResp ExtendedMedia
ptrSendMediaResp *ExtendedMedia
sendMediaError ErrorResponse
tmp interface{}
)
// decide whether unmarshal SendMediaResponse / ErrorResponse
if resp.GetStatusCode() == 200 {
tmp = &sendMediaResp
ptrSendMediaResp = &sendMediaResp
} else {
tmp = &sendMediaError
ptrSendMediaResp = nil
}
body := resp.GetBody()
// json to struct
if err := json.Unmarshal([]byte(body), tmp); err != nil {
return resp, nil, ErrorResponse{}, NewError(ErrorCodeJSONUnmarshal, err.Error())
}
return resp, ptrSendMediaResp, sendMediaError, nil
}