-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathPexelsClient.cs
362 lines (302 loc) · 15.8 KB
/
PexelsClient.cs
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
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
using Newtonsoft.Json;
using PexelsDotNetSDK.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Web;
namespace PexelsDotNetSDK.Api
{
/// <summary>
/// It is free to sign up and use the Pexels API.
/// - Sign Up here: https://www.pexels.com
/// - visit https://www.pexels.com/api/new/ to obtain your API key
/// </summary>
public class PexelsClient
{
private static HttpClient client;
private static string _token = "";
private static string _baseAddress = BaseConstants.API_URL;
private static string _apiVersion = BaseConstants.API_URL_VERSION;
private static int _timeoutSecs = BaseConstants.REQUEST_TIMEOUT_SECS;
private static string _version = BaseConstants.VERSION;
private bool isValidColor(string color)
{
Regex regex = new Regex("^#(?:[0-9a-fA-F]{3}){1,2}$");
return BaseConstants.COLORS.Contains(color.ToLower()) || regex.IsMatch(color);
}
private bool isValidSize(string size)
{
return BaseConstants.SIZES.Contains(size.ToLower());
}
private bool isValidOrientation(string orientation)
{
return BaseConstants.ORIENTATIONS.Contains(orientation.ToLower());
}
public PexelsClient(string token)
{
_token = token;
if (client == null)
{
this.CreateClient();
}
SetupClientAuthHeader(client);
}
private HttpClient CreateClient()
{
client = new HttpClient();
SetupClientDefaults(client);
return client;
}
protected virtual void SetupClientDefaults(HttpClient client)
{
client.Timeout = TimeSpan.FromSeconds(_timeoutSecs);
client.BaseAddress = new Uri(_baseAddress);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("User-Agent", $"Pexels/.NET ({_version})");
}
protected virtual void SetupClientAuthHeader(HttpClient client)
{
client.DefaultRequestHeaders.Remove("Authorization");
client.DefaultRequestHeaders.Add("Authorization", _token);
}
/// <summary>
/// This endpoint enables you to search Pexels for any topic that you would like. For example your query could be something broad like 'Nature',
/// 'Tigers', 'People'. Or it could be something specific like 'Group of people working'.
/// </summary>
/// <param name="query">The search query. Ocean, Tigers, Pears, etc.</param>
/// <param name="orientation">Desired photo orientation. The current supported orientations are: landscape, portrait or square</param>
/// <param name="size">Minimum photo size. The current supported sizes are: large(24MP), medium(12MP) or small(4MP)</param>
/// <param name="color">Desired photo color. Supported colors: red, orange, yellow, green, turquoise, blue, violet, pink, brown, black, gray, white or any hexidecimal color code (eg. #ffffff)</param>
/// <param name="locale">The locale of the search you are performing. The current supported locales are: 'en-US' 'pt-BR' 'es-ES' 'ca-ES' 'de-DE' 'it-IT' 'fr-FR' 'sv-SE' 'id-ID' 'pl-PL' 'ja-JP' 'zh-TW' 'zh-CN' 'ko-KR' 'th-TH' 'nl-NL' 'hu-HU' 'vi-VN' 'cs-CZ' 'da-DK' 'fi-FI' 'uk-UA' 'el-GR' 'ro-RO' 'nb-NO' 'sk-SK' 'tr-TR' 'ru-RU'.</param>
/// <param name="page">The number of the page you are requesting. Default: 1</param>
/// <param name="pageSize">The number of results you are requesting per page. Default: 15 Max: 80</param>
/// <returns></returns>
public async Task<PhotoPage> SearchPhotosAsync(string query, string orientation = "", string size = "", string color = "", string locale = "", int page = 1, int pageSize = 15)
{
if (pageSize > 80) pageSize = 80;
if (pageSize <= 0) pageSize = 1;
if (page <= 0) page = 1;
string _requestUrl = $"{_apiVersion}search?query={Uri.EscapeDataString(query)}&page={page}&per_page={pageSize}";
if (!string.IsNullOrEmpty(locale))
{
_requestUrl += $"&locale={locale}";
}
if (!string.IsNullOrEmpty(orientation) && isValidOrientation(orientation))
{
_requestUrl += $"&orientation={orientation}";
}
if (!string.IsNullOrEmpty(size) && isValidSize(size))
{
_requestUrl += $"&size={size}";
}
if (!string.IsNullOrEmpty(color) && isValidColor(color))
{
_requestUrl += $"&color={HttpUtility.UrlEncode(color)}";
}
HttpResponseMessage response = await client.GetAsync(_requestUrl);
var output = await ProcessResult<PhotoPage>(response);
output.rateLimit = ProcessRateLimits(response);
return output;
}
/// <summary>
/// This endpoint allows you to get all the collections you've created on Pexels.
/// </summary>
/// <param name="page">The number of the page you are requesting. Default: 1</param>
/// <param name="pageSize">The number of results you are requesting per page. Default: 15 Max: 80</param>
/// <returns></returns>
public async Task<CollectionPage> CollectionsAsync(int page = 1, int pageSize = 15)
{
if (pageSize > 80) pageSize = 80;
if (pageSize <= 0) pageSize = 1;
if (page <= 0) page = 1;
string _requestUrl = $"{_apiVersion}collections?page={page}&per_page={pageSize}";
HttpResponseMessage response = await client.GetAsync(_requestUrl);
var output = await ProcessResult<CollectionPage>(response);
output.rateLimit = ProcessRateLimits(response);
return output;
}
/// <summary>
/// This endpoint returns a list of featured collections
/// </summary>
/// <param name="page">The number of the page you are requesting. Default: 1</param>
/// <param name="pageSize">The number of results you are requesting per page. Default: 15 Max: 80</param>
/// <returns></returns>
public async Task<CollectionPage> FeaturedCollectionsAsync(int page = 1, int pageSize = 15)
{
if (pageSize > 80) pageSize = 80;
if (pageSize <= 0) pageSize = 1;
if (page <= 0) page = 1;
string _requestUrl = $"{_apiVersion}collections/featured?page={page}&per_page={pageSize}";
HttpResponseMessage response = await client.GetAsync(_requestUrl);
var output = await ProcessResult<CollectionPage>(response);
output.rateLimit = ProcessRateLimits(response);
return output;
}
/// <summary>
/// This endpoint gets the media of a specific collection.
/// </summary>
/// <param name="id">The Collection Id</param>
/// <param name="page">The number of the page you are requesting. Default: 1</param>
/// <param name="pageSize">The number of results you are requesting per page. Default: 15 Max: 80</param>
/// <param name="type">Filter results to a specific media type (`videos` or `photos`). Leave blank for all results.</param>
/// <returns></returns>
public async Task<CollectionMediaPage> GetCollectionAsync(string id, int page = 1, int pageSize = 15, string type = null)
{
if (pageSize > 80) pageSize = 80;
if (pageSize <= 0) pageSize = 1;
if (page <= 0) page = 1;
string _requestUrl = $"{_apiVersion}collections/{id}?page={page}&per_page={pageSize}&type={type}";
HttpResponseMessage response = await client.GetAsync(_requestUrl);
var output = await ProcessResult<CollectionMediaPage>(response);
output.rateLimit = ProcessRateLimits(response);
return output;
}
/// <summary>
/// This endpoint enables you to receive real-time photos curated by the Pexels team.
/// We add at least one new photo per hour to our curated list so that you always get a changing selection of trending photos.
/// </summary>
/// <param name="page">The number of the page you are requesting. Default: 1</param>
/// <param name="pageSize">The number of results you are requesting per page. Default: 15 Max: 80</param>
/// <returns></returns>
public async Task<PhotoPage> CuratedPhotosAsync(int page = 1, int pageSize = 15)
{
if (pageSize > 80) pageSize = 80;
if (pageSize <= 0) pageSize = 1;
if (page <= 0) page = 1;
string _requestUrl = $"{_apiVersion}curated?page={page}&per_page={pageSize}";
HttpResponseMessage response = await client.GetAsync(_requestUrl);
var output = await ProcessResult<PhotoPage>(response);
output.rateLimit = ProcessRateLimits(response);
return output;
}
/// <summary>
/// Retrieve a specific Photo from its id.
/// </summary>
/// <param name="id">The id of the photo you are requesting.</param>
/// <returns></returns>
public async Task<Photo> GetPhotoAsync(int id)
{
string _requestUrl = $"{_apiVersion}photos/{id}";
HttpResponseMessage response = await client.GetAsync(_requestUrl);
return await ProcessResult<Photo>(response);
}
/// <summary>
/// This endpoint enables you to search Pexels for any topic that you would like. For example your query could be something broad like 'Nature',
/// 'Tigers', 'People'. Or it could be something specific like 'Group of people working'.
/// </summary>
/// <param name="query">The search query. Ocean, Tigers, Pears, etc.</param>
/// <param name="orientation">Desired photo orientation. The current supported orientations are: landscape, portrait or square</param>
/// <param name="size">Minimum photo size. The current supported sizes are: large(24MP), medium(12MP) or small(4MP)</param>
/// <param name="locale">The locale of the search you are performing. The current supported locales are: 'en-US' 'pt-BR' 'es-ES' 'ca-ES' 'de-DE' 'it-IT' 'fr-FR' 'sv-SE' 'id-ID' 'pl-PL' 'ja-JP' 'zh-TW' 'zh-CN' 'ko-KR' 'th-TH' 'nl-NL' 'hu-HU' 'vi-VN' 'cs-CZ' 'da-DK' 'fi-FI' 'uk-UA' 'el-GR' 'ro-RO' 'nb-NO' 'sk-SK' 'tr-TR' 'ru-RU'.</param>
/// <param name="page">The number of the page you are requesting. Default: 1</param>
/// <param name="pageSize">The number of results you are requesting per page. Default: 15 Max: 80</param>
/// <returns></returns>
public async Task<VideoPage> SearchVideosAsync(string query, string orientation = "", string size = "", string locale = "", int page = 1, int pageSize = 15)
{
if (pageSize > 80) pageSize = 80;
if (pageSize <= 0) pageSize = 1;
if (page <= 0) page = 1;
string _requestUrl = $"videos/search?query={Uri.EscapeDataString(query)}&page={page}&per_page={pageSize}";
if (!string.IsNullOrEmpty(locale))
{
_requestUrl += $"&locale={locale}";
}
if (!string.IsNullOrEmpty(orientation) && isValidOrientation(orientation))
{
_requestUrl += $"&orientation={orientation}";
}
if (!string.IsNullOrEmpty(size) && isValidSize(size))
{
_requestUrl += $"&size={size}";
}
HttpResponseMessage response = await client.GetAsync(_requestUrl);
var output = await ProcessResult<VideoPage>(response);
output.rateLimit = ProcessRateLimits(response);
return output;
}
/// <summary>
/// This endpoint enables you to receive the current popular Pexels videos.
/// </summary>
/// <param name="page">The number of the page you are requesting. Default: 1</param>
/// <param name="pageSize">The number of results you are requesting per page. Default: 15 Max: 80</param>
/// <param name="minWidth">The minimum width in pixels of the returned videos.</param>
/// <param name="minHeight">The minimum height in pixels of the returned videos.</param>
/// <param name="minDurationSecs">The minimum duration in seconds of the returned videos.</param>
/// <param name="maxDurationSecs">The maximum duration in seconds of the returned videos.</param>
/// <returns></returns>
public async Task<VideoPage> PopularVideosAsync(int page = 1, int pageSize = 15,
int minWidth = 0, int minHeight = 0, int minDurationSecs = 0, int maxDurationSecs = 0)
{
if (pageSize > 80) pageSize = 80;
if (pageSize <= 0) pageSize = 1;
if (page <= 0) page = 1;
string _requestUrl = $"videos/popular?page={page}&per_page={pageSize}";
if (minWidth > 0)
{
_requestUrl += $"&min_width={minWidth}";
}
if (minHeight > 0)
{
_requestUrl += $"&min_height={minHeight}";
}
if (minDurationSecs > 0)
{
_requestUrl += $"&min_duration={minDurationSecs}";
}
if (maxDurationSecs > 0)
{
_requestUrl += $"&max_duration={maxDurationSecs}";
}
HttpResponseMessage response = await client.GetAsync(_requestUrl);
var output = await ProcessResult<VideoPage>(response);
output.rateLimit = ProcessRateLimits(response);
return output;
}
/// <summary>
/// Retrieve a specific Video from its id.
/// </summary>
/// <param name="id">The id of the video you are requesting.</param>
/// <returns></returns>
public async Task<Video> GetVideoAsync(int id)
{
string _requestUrl = $"videos/videos/{id}";
HttpResponseMessage response = await client.GetAsync(_requestUrl);
return await ProcessResult<Video>(response);
}
private async Task<T> ProcessResult<T>(HttpResponseMessage response)
{
string responseBody = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode)
{
return JsonConvert.DeserializeObject<T>(responseBody);
}
throw new ErrorResponse(response.StatusCode, responseBody);
}
private RateLimit ProcessRateLimits(HttpResponseMessage response)
{
try
{
DateTime start = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
var _resetValue = response.Headers.TryGetValues("X-Ratelimit-Reset", out var vals1) ? vals1.FirstOrDefault() : null;
var _limitValue = response.Headers.TryGetValues("X-Ratelimit-Limit", out var vals2) ? vals2.FirstOrDefault() : "0";
var _remainingValue = response.Headers.TryGetValues("X-Ratelimit-Remaining", out var vals3) ? vals3.FirstOrDefault() : "0";
var output = new RateLimit()
{
Limit = Convert.ToInt64(_limitValue),
Remaining = Convert.ToInt64(_remainingValue),
Reset = _resetValue != null ? start.AddMilliseconds(Convert.ToInt64(_resetValue)).ToLocalTime() : start.ToLocalTime()
};
return output;
}
catch (Exception e) { }
return null;
}
}
}