pexels 0.0.4 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 659313ec19604a9af5e891f33464f00e417f7e30578b7a926b6911bd03140c2f
4
- data.tar.gz: 2366d7b62d237e92066faf3616ce3a654f94212334e55926979f68609dd084b7
3
+ metadata.gz: 7f9609676bbaebe34889f5c6483f15f41831439eced062f91a7a1eb8fb0c1d8e
4
+ data.tar.gz: a7be0c896cacd8e3bf02aaf5a87eaee7c0a7c3a17d1118b87f114da208972e0f
5
5
  SHA512:
6
- metadata.gz: 1e20e097cd5e45e82397386cb91f831d7dfce398d53ecaeecd67d3c0cb7c02ec7d3b4ba37ee349174fce076497d73299401b7a0556db33a94b868de63b070651
7
- data.tar.gz: 297a760a1638110b75173c50231076174fa85972e4f7e2ff0e8d0ec0dd53c9de710dada38c09ce0b68f4710950a2ad678bf508fc5cfe29d2f108dde367575649
6
+ metadata.gz: 506d3d399c0cc6655daead44255597131d162808b6b206e32aa7fd60022883703330f2527fb6d092b944ba31a9067b813f6e27f355f7dbc87dcbb3ab95984f2c
7
+ data.tar.gz: c72ebaa5715f520f74a05941f384bcd1e6db62d45662f07f9a8afbc5236b85c6aa4527a1ccf6f2a74b9d95f36e42fe56c12333ee12411076a8cb6b0170c75105
data/.gitignore CHANGED
@@ -1,3 +1,4 @@
1
1
  .gems.up.to.date
2
2
  .env
3
3
  *.gem
4
+ .headers
data/CHANGES.md ADDED
@@ -0,0 +1,11 @@
1
+ # Change log
2
+
3
+ ## 0.1.0
4
+ * Add support for returning collections belonging to the API user.
5
+ * Add support for returning media from a collection.
6
+
7
+ ## 0.0.4
8
+ * Add `find` as an alias for `photos[]` and `videos[]`.
9
+
10
+ ## 0.0.3
11
+ * Initial release.
data/lib/pexels.rb CHANGED
@@ -1,19 +1,41 @@
1
1
  module Pexels
2
- @api_base_url = 'https://api.pexels.com'
2
+ @api_base_url = ENV['PEXELS_API_BASE_URL'] || 'https://api.pexels.com'
3
+ @api_version = ENV['PEXELS_API_VERSION'] || 'v1'
3
4
 
4
5
  class << self
5
- attr_reader :api_base_url
6
+ attr_reader :api_base_url, :api_version
7
+
8
+ # Local headers can be defined inside a `.headers` file at the project root,
9
+ # with the following format:
10
+ #
11
+ # header1=value
12
+ # header2=value
13
+ # etc.
14
+ #
15
+ def local_headers
16
+ @local_headers ||= if File.exist?('.headers')
17
+ File.read('.headers').split.to_h { |header| header.split('=') }
18
+ else
19
+ {}
20
+ end
21
+ end
6
22
  end
7
23
  end
8
24
 
9
25
  require_relative 'pexels/client'
26
+ require_relative 'pexels/client/collections'
10
27
  require_relative 'pexels/client/photos'
11
28
  require_relative 'pexels/client/videos'
12
29
  require_relative 'pexels/version'
13
30
  require_relative 'pexels/errors'
31
+ require_relative 'pexels/collection'
14
32
  require_relative 'pexels/photo'
15
33
  require_relative 'pexels/video'
16
34
  require_relative 'pexels/video/file'
17
35
  require_relative 'pexels/video/picture'
18
36
  require_relative 'pexels/user'
19
- require_relative 'pexels/response'
37
+ require_relative 'pexels/paginated_response'
38
+ require_relative 'pexels/collection_set'
39
+ require_relative 'pexels/collection_media_set'
40
+ require_relative 'pexels/photo_set'
41
+ require_relative 'pexels/video_set'
data/lib/pexels/client.rb CHANGED
@@ -4,7 +4,6 @@ class Pexels::Client
4
4
  attr_reader :api_key,
5
5
  :ratelimit_remaining
6
6
 
7
-
8
7
  def initialize(api_key = ENV['PEXELS_API_KEY'])
9
8
  @api_key = api_key
10
9
  end
@@ -17,17 +16,26 @@ class Pexels::Client
17
16
  @videos ||= Pexels::Client::Videos.new(self)
18
17
  end
19
18
 
19
+ def collections
20
+ @collections ||= Pexels::Client::Collections.new(self)
21
+ end
22
+
20
23
  def request(path, method: 'GET', params: {})
24
+ url = File.join(Pexels.api_base_url, path)
25
+ headers = {
26
+ 'Authorization' => api_key
27
+ }.merge(Pexels.local_headers)
28
+
29
+ puts "Requesting #{url} with #{headers}" if ENV['DEBUG']
30
+
21
31
  results = Requests.request(
22
32
  method,
23
- "#{Pexels.api_base_url}#{path}",
33
+ url,
24
34
  params: params,
25
- headers: {
26
- 'Authorization' => api_key
27
- }
35
+ headers: headers
28
36
  )
29
37
 
30
- @ratelimit_remaining = results.headers['x-ratelimit-remaining'].first.to_i
38
+ @ratelimit_remaining = results.headers['x-ratelimit-remaining']&.first&.to_i
31
39
 
32
40
  return JSON.parse(results.body)
33
41
  rescue StandardError => exception
@@ -0,0 +1,29 @@
1
+ class Pexels::Client::Collections
2
+ def initialize(client)
3
+ @client = client
4
+ end
5
+
6
+ def all(per_page: 15, page: 1)
7
+ response = @client.request(
8
+ '/collections',
9
+ params: {
10
+ per_page: per_page,
11
+ page: page
12
+ })
13
+
14
+ Pexels::CollectionSet.new(response)
15
+ end
16
+
17
+ def [](id, type: nil, per_page: 15, page: 1)
18
+ response = @client.request(
19
+ "/collections/#{id}",
20
+ params: {
21
+ per_page: per_page,
22
+ page: page,
23
+ type: type
24
+ })
25
+
26
+ Pexels::CollectionMediaSet.new(response)
27
+ end
28
+ alias_method :find, :[]
29
+ end
@@ -5,14 +5,14 @@ class Pexels::Client::Photos
5
5
  end
6
6
 
7
7
  def [](id)
8
- response = @client.request("/v1/photos/#{id}")
8
+ response = @client.request("#{Pexels.api_version}/photos/#{id}")
9
9
  Pexels::Photo.new(response)
10
10
  end
11
11
  alias_method :find, :[]
12
12
 
13
13
  def search(query, per_page: 15, page: 1, locale: 'en-US')
14
14
  response = @client.request(
15
- '/v1/search',
15
+ "#{Pexels.api_version}/search",
16
16
  params: {
17
17
  query: query,
18
18
  per_page: per_page,
@@ -21,18 +21,18 @@ class Pexels::Client::Photos
21
21
  }
22
22
  )
23
23
 
24
- Pexels::Response.new(response)
24
+ Pexels::PhotoSet.new(response)
25
25
  end
26
26
 
27
27
  def curated(per_page: 15, page: 1)
28
28
  response = @client.request(
29
- '/v1/curated',
29
+ "#{Pexels.api_version}/curated",
30
30
  params: {
31
31
  per_page: per_page,
32
32
  page: page,
33
33
  }
34
34
  )
35
35
 
36
- Pexels::Response.new(response)
36
+ Pexels::PhotoSet.new(response)
37
37
  end
38
38
  end
@@ -20,7 +20,7 @@ class Pexels::Client::Videos
20
20
  }
21
21
  )
22
22
 
23
- Pexels::Response.new(response)
23
+ Pexels::VideoSet.new(response)
24
24
  end
25
25
 
26
26
  def popular(per_page: 15, page: 1)
@@ -32,6 +32,6 @@ class Pexels::Client::Videos
32
32
  }
33
33
  )
34
34
 
35
- Pexels::Response.new(response)
35
+ Pexels::VideoSet.new(response)
36
36
  end
37
37
  end
@@ -0,0 +1,25 @@
1
+ module Pexels
2
+ class Collection
3
+ attr_reader :id,
4
+ :title,
5
+ :description,
6
+ :private,
7
+ :media_count,
8
+ :photos_count,
9
+ :videos_count
10
+
11
+
12
+ def initialize(attrs)
13
+ @id = attrs.fetch('id')
14
+ @title = attrs.fetch('title')
15
+ @description = attrs.fetch('description')
16
+ @private = attrs.fetch('private')
17
+ @media_count = attrs.fetch('media_count')
18
+ @photos_count = attrs.fetch('photos_count')
19
+ @videos_count = attrs.fetch('videos_count')
20
+
21
+ rescue KeyError => exception
22
+ raise Pexels::MalformedAPIResponseError.new(exception)
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,31 @@
1
+ module Pexels
2
+ class CollectionMediaSet < PaginatedResponse
3
+ alias_method :media, :data
4
+ public :media
5
+
6
+ attr_reader :id
7
+
8
+ def initialize(attrs)
9
+ super
10
+ @id = attrs.fetch('id')
11
+ @data = attrs.fetch('media', []).map do |attrs|
12
+ if attrs['type'] == 'Photo'
13
+ Pexels::Photo.new(attrs)
14
+ elsif attrs['type'] == 'Video'
15
+ Pexels::Video.new(attrs)
16
+ end
17
+ end
18
+
19
+ rescue KeyError => exception
20
+ raise Pexels::MalformedAPIResponseError.new(exception)
21
+ end
22
+
23
+ def photos
24
+ @photos ||= media.select { |m| m.is_a?(Pexels::Photo) }
25
+ end
26
+
27
+ def videos
28
+ @videos ||= media.select { |m| m.is_a?(Pexels::Video) }
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,11 @@
1
+ module Pexels
2
+ class CollectionSet < PaginatedResponse
3
+ alias_method :collections, :data
4
+ public :collections
5
+
6
+ def initialize(attrs)
7
+ super
8
+ @data = attrs.fetch('collections', []).map { |attrs| Pexels::Collection.new(attrs) }
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,28 @@
1
+ module Pexels
2
+ class PaginatedResponse
3
+ include Enumerable
4
+
5
+ attr_reader :total_results,
6
+ :page,
7
+ :per_page,
8
+ :next_page,
9
+ :data
10
+
11
+ private :data
12
+
13
+ def initialize(attrs)
14
+ @total_results = attrs.fetch('total_results', nil)
15
+ @page = attrs.fetch('page')
16
+ @per_page = attrs.fetch('per_page')
17
+ @next_page = attrs.fetch('next_page', nil)
18
+ end
19
+
20
+ def each(&block)
21
+ if block_given?
22
+ data.each(&block)
23
+ else
24
+ to_enum(:each)
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,14 @@
1
+ module Pexels
2
+ class PhotoSet < PaginatedResponse
3
+ alias_method :photos, :data
4
+ public :photos
5
+
6
+ def initialize(attrs)
7
+ super
8
+ @data = attrs.fetch('photos', []).map { |attrs| Pexels::Photo.new(attrs) }
9
+
10
+ rescue KeyError => exception
11
+ raise Pexels::MalformedAPIResponseError.new(exception)
12
+ end
13
+ end
14
+ end
@@ -1,3 +1,3 @@
1
1
  module Pexels
2
- VERSION = '0.0.4'
2
+ VERSION = '0.1.0'
3
3
  end
@@ -0,0 +1,14 @@
1
+ module Pexels
2
+ class VideoSet < PaginatedResponse
3
+ alias_method :videos, :data
4
+ public :videos
5
+
6
+ def initialize(attrs)
7
+ super
8
+ @data = attrs.fetch('videos', []).map { |attrs| Pexels::Video.new(attrs) }
9
+
10
+ rescue KeyError => exception
11
+ raise Pexels::MalformedAPIResponseError.new(exception)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,81 @@
1
+ require 'minitest/autorun'
2
+ require 'pexels'
3
+
4
+ class TestCollections < Minitest::Test
5
+
6
+ def setup
7
+ @client = Pexels::Client.new(ENV.fetch('PEXELS_API_KEY'))
8
+ @collection = @client.collections.all(per_page: 1).first
9
+ end
10
+
11
+ def test_all
12
+ search_result = @client.collections.all
13
+
14
+ assert search_result.is_a? Pexels::CollectionSet
15
+ assert_equal search_result.per_page, 15
16
+ assert_equal search_result.page, 1
17
+
18
+ assert search_result.collections.is_a? Array
19
+ assert search_result.collections.any?
20
+ assert search_result.first.is_a? Pexels::Collection
21
+
22
+ search_result_with_params = @client.collections.all(per_page: 1, page: 2)
23
+ assert_equal search_result_with_params.per_page, 1
24
+ assert_equal search_result_with_params.page, 2
25
+ assert_equal search_result_with_params.collections.length, 1
26
+ end
27
+
28
+ def test_get_collection_media
29
+ collection = @client.collections[@collection.id]
30
+ assert collection.is_a? Pexels::CollectionMediaSet
31
+ assert_equal collection.id, @collection.id
32
+
33
+ assert collection.media.is_a? Array
34
+ assert collection.media.any?
35
+
36
+ assert_includes([Pexels::Photo, Pexels::Video], collection.media.first.class)
37
+
38
+ refute_includes([Pexels::Video], collection.photos.map(&:class))
39
+ refute_includes([Pexels::Photo], collection.videos.map(&:class))
40
+ end
41
+
42
+ def test_get_collection_photos
43
+ collection = @client.collections[@collection.id, type: 'photos']
44
+ assert collection.is_a? Pexels::CollectionMediaSet
45
+ assert collection.media.is_a? Array
46
+ assert collection.media.all? { |m| m.is_a?(Pexels::Photo) }
47
+ end
48
+
49
+ def test_get_collection_videos
50
+ collection = @client.collections[@collection.id, type: 'videos']
51
+ assert collection.is_a? Pexels::CollectionMediaSet
52
+ assert collection.media.is_a? Array
53
+ assert collection.media.all? { |m| m.is_a?(Pexels::Video) }
54
+ end
55
+
56
+ def test_get_collection_invalid_type
57
+ collection = @client.collections[@collection.id, type: 'foo']
58
+ assert collection.is_a? Pexels::CollectionMediaSet
59
+ assert collection.media.is_a? Array
60
+ assert collection.any?
61
+ end
62
+
63
+ def test_get_collection_pagination
64
+ collection = @client.collections[@collection.id, per_page: 1, page: 1]
65
+ assert collection.is_a? Pexels::CollectionMediaSet
66
+ assert collection.media.is_a? Array
67
+ assert collection.media.any?
68
+
69
+ assert_equal collection.per_page, 1
70
+ assert_equal collection.page, 1
71
+ assert_equal collection.media.length, 1
72
+ end
73
+
74
+ def test_invalid_get_collection
75
+ @client.collections['this-is-not-a-valid-id']
76
+ raise 'This should not happen'
77
+ rescue StandardError => exception
78
+ assert exception.is_a? Pexels::APIError
79
+ assert_equal exception.message, 'Not Found'
80
+ end
81
+ end
data/test/photo_test.rb CHANGED
@@ -5,13 +5,13 @@ class TestPhoto < Minitest::Test
5
5
 
6
6
  def setup
7
7
  @client = Pexels::Client.new(ENV.fetch('PEXELS_API_KEY'))
8
- @photo = @client.photos.search('test', per_page: 1).photos.first
8
+ @photo = @client.photos.search('test', per_page: 1).first
9
9
  end
10
10
 
11
11
  def test_successful_searches
12
12
  search_result = @client.photos.search('test')
13
13
 
14
- assert search_result.is_a? Pexels::Response
14
+ assert search_result.is_a? Pexels::PhotoSet
15
15
  assert search_result.next_page.is_a? String
16
16
  assert search_result.total_results.is_a? Integer
17
17
  assert_equal search_result.per_page, 15
@@ -19,7 +19,7 @@ class TestPhoto < Minitest::Test
19
19
 
20
20
  assert search_result.photos.is_a? Array
21
21
  assert search_result.photos.any?
22
- assert search_result.photos.first.is_a? Pexels::Photo
22
+ assert search_result.first.is_a? Pexels::Photo
23
23
 
24
24
  search_result_with_params = @client.photos.search('test', per_page: 1, page: 2)
25
25
  assert_equal search_result_with_params.per_page, 1
@@ -30,14 +30,14 @@ class TestPhoto < Minitest::Test
30
30
  def test_curated_photos
31
31
  search_result = @client.photos.curated
32
32
 
33
- assert search_result.is_a? Pexels::Response
33
+ assert search_result.is_a? Pexels::PhotoSet
34
34
  assert search_result.next_page.is_a? String
35
35
  assert_equal search_result.per_page, 15
36
36
  assert_equal search_result.page, 1
37
37
 
38
38
  assert search_result.photos.is_a? Array
39
39
  assert search_result.photos.any?
40
- assert search_result.photos.first.is_a? Pexels::Photo
40
+ assert search_result.first.is_a? Pexels::Photo
41
41
 
42
42
  search_result_with_params = @client.photos.curated(per_page: 1, page: 2)
43
43
  assert_equal search_result_with_params.per_page, 1
data/test/video_test.rb CHANGED
@@ -5,20 +5,20 @@ class TestVideo < Minitest::Test
5
5
 
6
6
  def setup
7
7
  @client = Pexels::Client.new(ENV.fetch('PEXELS_API_KEY'))
8
- @video = @client.videos.search('test', per_page: 1).videos.first
8
+ @video = @client.videos.search('test', per_page: 1).first
9
9
  end
10
10
 
11
11
  def test_successful_searches
12
12
  search_result = @client.videos.search('test')
13
13
 
14
- assert search_result.is_a? Pexels::Response
14
+ assert search_result.is_a? Pexels::VideoSet
15
15
  assert search_result.total_results.is_a? Integer
16
16
  assert_equal search_result.per_page, 15
17
17
  assert_equal search_result.page, 1
18
18
 
19
19
  assert search_result.videos.is_a? Array
20
20
  assert search_result.videos.any?
21
- assert search_result.videos.first.is_a? Pexels::Video
21
+ assert search_result.first.is_a? Pexels::Video
22
22
 
23
23
  search_result_with_params = @client.videos.search('test', per_page: 1, page: 2)
24
24
  assert_equal search_result_with_params.per_page, 1
@@ -29,13 +29,13 @@ class TestVideo < Minitest::Test
29
29
  def test_popular_videos
30
30
  search_result = @client.videos.popular
31
31
 
32
- assert search_result.is_a? Pexels::Response
32
+ assert search_result.is_a? Pexels::VideoSet
33
33
  assert_equal search_result.per_page, 15
34
34
  assert_equal search_result.page, 1
35
35
 
36
36
  assert search_result.videos.is_a? Array
37
37
  assert search_result.videos.any?
38
- assert search_result.videos.first.is_a? Pexels::Video
38
+ assert search_result.first.is_a? Pexels::Video
39
39
 
40
40
  search_result_with_params = @client.videos.popular(per_page: 1, page: 2)
41
41
  assert_equal search_result_with_params.per_page, 1
@@ -70,10 +70,6 @@ class TestVideo < Minitest::Test
70
70
  raise 'This should not happen'
71
71
  rescue StandardError => exception
72
72
  assert exception.is_a? Pexels::APIError
73
- #assert_equal exception.message, 'Not Found'
74
- #
75
- ## This is incorrect behavior from the API, which we should change
76
- # once its fixed.
77
- assert_equal exception.message, 'Internal Server Error'
73
+ assert_equal exception.message, 'Not Found'
78
74
  end
79
75
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pexels
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pexels dev team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-21 00:00:00.000000000 Z
11
+ date: 2021-04-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: requests
@@ -34,23 +34,31 @@ files:
34
34
  - ".env.sample"
35
35
  - ".gems"
36
36
  - ".gitignore"
37
+ - CHANGES.md
37
38
  - LICENSE
38
39
  - Makefile
39
40
  - README.md
40
41
  - lib/pexels.rb
41
42
  - lib/pexels/client.rb
43
+ - lib/pexels/client/collections.rb
42
44
  - lib/pexels/client/photos.rb
43
45
  - lib/pexels/client/videos.rb
46
+ - lib/pexels/collection.rb
47
+ - lib/pexels/collection_media_set.rb
48
+ - lib/pexels/collection_set.rb
44
49
  - lib/pexels/errors.rb
50
+ - lib/pexels/paginated_response.rb
45
51
  - lib/pexels/photo.rb
46
- - lib/pexels/response.rb
52
+ - lib/pexels/photo_set.rb
47
53
  - lib/pexels/user.rb
48
54
  - lib/pexels/version.rb
49
55
  - lib/pexels/video.rb
50
56
  - lib/pexels/video/file.rb
51
57
  - lib/pexels/video/picture.rb
58
+ - lib/pexels/video_set.rb
52
59
  - pexels.gemspec
53
60
  - test/client_test.rb
61
+ - test/collection_test.rb
54
62
  - test/photo_test.rb
55
63
  - test/video_test.rb
56
64
  homepage: https://github.com/pexels/pexels-ruby
@@ -1,20 +0,0 @@
1
- class Pexels::Response
2
- attr_reader :photos,
3
- :videos,
4
- :total_results,
5
- :page,
6
- :per_page,
7
- :next_page
8
-
9
- def initialize(attrs, type: :Photo)
10
- @total_results = attrs.fetch('total_results', nil)
11
- @page = attrs.fetch('page')
12
- @per_page = attrs.fetch('per_page')
13
- @next_page = attrs.fetch('next_page', nil)
14
-
15
- @photos = attrs.fetch('photos', []).map { |attrs| Pexels::Photo.new(attrs) }
16
- @videos = attrs.fetch('videos', []).map { |attrs| Pexels::Video.new(attrs) }
17
-
18
- return self
19
- end
20
- end