trailer_vote-api 0.5.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.
Files changed (39) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/.rubocop.yml +29 -0
  4. data/CHANGELOG.md +3 -0
  5. data/Gemfile +6 -0
  6. data/Gemfile.lock +77 -0
  7. data/README.md +184 -0
  8. data/Rakefile +12 -0
  9. data/bin/console +15 -0
  10. data/bin/setup +8 -0
  11. data/lib/trailer_vote/api/autoload.rb +15 -0
  12. data/lib/trailer_vote/api/composable/common.rb +61 -0
  13. data/lib/trailer_vote/api/composable/get.rb +54 -0
  14. data/lib/trailer_vote/api/configuration.rb +69 -0
  15. data/lib/trailer_vote/api/errors.rb +62 -0
  16. data/lib/trailer_vote/api/links.rb +51 -0
  17. data/lib/trailer_vote/api/place/create.rb +65 -0
  18. data/lib/trailer_vote/api/place/find.rb +49 -0
  19. data/lib/trailer_vote/api/place.rb +19 -0
  20. data/lib/trailer_vote/api/product/create.rb +56 -0
  21. data/lib/trailer_vote/api/product/find.rb +37 -0
  22. data/lib/trailer_vote/api/product/image/create.rb +66 -0
  23. data/lib/trailer_vote/api/product/image/find.rb +39 -0
  24. data/lib/trailer_vote/api/product/image/urls.rb +57 -0
  25. data/lib/trailer_vote/api/product/image.rb +31 -0
  26. data/lib/trailer_vote/api/product/lookup.rb +81 -0
  27. data/lib/trailer_vote/api/product/place/link.rb +64 -0
  28. data/lib/trailer_vote/api/product/place.rb +31 -0
  29. data/lib/trailer_vote/api/product/update.rb +72 -0
  30. data/lib/trailer_vote/api/product/video/create.rb +66 -0
  31. data/lib/trailer_vote/api/product/video/find.rb +39 -0
  32. data/lib/trailer_vote/api/product/video/urls.rb +57 -0
  33. data/lib/trailer_vote/api/product/video.rb +31 -0
  34. data/lib/trailer_vote/api/product.rb +25 -0
  35. data/lib/trailer_vote/api/type_registry.rb +93 -0
  36. data/lib/trailer_vote/api/version.rb +7 -0
  37. data/lib/trailer_vote/api.rb +42 -0
  38. data/trailer_vote-api.gemspec +35 -0
  39. metadata +234 -0
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'trailer_vote/api/composable/common'
4
+ require 'trailer_vote/api/place'
5
+ require 'trailer_vote/api/place/find'
6
+
7
+ module TrailerVote
8
+ module Api
9
+ class Place
10
+ class Find
11
+ def create
12
+ Create.new(configuration: configuration, place: self)
13
+ end
14
+ end
15
+
16
+ class Create
17
+ include Composable::Common
18
+
19
+ CONTENT = MediaTypes::Place.to_constructable.version(2).view('create')
20
+ SUCCESS = MediaTypes::Place.to_constructable.version(2)
21
+ FAILURE = MediaTypes::Errors.to_constructable.version(1)
22
+
23
+ ACCEPT = [SUCCESS.to_s, FAILURE.to_s(0.1)].join(', ').freeze
24
+
25
+ def initialize(configuration:, place:)
26
+ self.configuration = configuration
27
+ self.place = place
28
+ end
29
+
30
+ def call(data:, url: resolve_url)
31
+ body = encode(data)
32
+ branch(
33
+ resolve_client.headers(
34
+ Headers::ACCEPT => ACCEPT,
35
+ Headers::CONTENT_TYPE => "#{CONTENT}; charset=#{body.encoding.name}"
36
+ ).post(url, body: body),
37
+ data: data
38
+ )
39
+ end
40
+
41
+ private
42
+
43
+ attr_accessor :place
44
+
45
+ def resolve_url
46
+ place.links.self
47
+ end
48
+
49
+ def encode(data)
50
+ TrailerVote::Api.encode(CONTENT, place: data)
51
+ end
52
+
53
+ def forward(result, data:)
54
+ return unless [307, 308].include?(result.status)
55
+ forward_klazz.new(configuration: configuration, place: place)
56
+ .call(data: data, url: redirected_url(result))
57
+ end
58
+
59
+ def redirect_klazz
60
+ Find
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'trailer_vote/api/composable/get'
4
+ require 'trailer_vote/api/place'
5
+
6
+ module TrailerVote
7
+ module Api
8
+ class Configuration
9
+ def place
10
+ Place::Find.new(configuration: self)
11
+ end
12
+ end
13
+
14
+ class Place
15
+ class Find
16
+ include Composable::Get
17
+
18
+ SUCCESS = MediaTypes::Place.to_constructable.version(2)
19
+ FAILURE = MediaTypes::Errors.to_constructable.version(1)
20
+
21
+ ACCEPT = [SUCCESS.to_s, FAILURE.to_s(0.1)].join(', ').freeze
22
+
23
+ def initialize(configuration:, result: nil)
24
+ self.configuration = configuration
25
+ self.result = result
26
+ end
27
+
28
+ def call(url: resolve_url)
29
+ puts url
30
+ return self if ok? || !url
31
+ branch(resolve_client.headers(Headers::ACCEPT => ACCEPT).get(url))
32
+ end
33
+
34
+ def resolve_url
35
+ configuration.links.place
36
+ end
37
+
38
+ def data
39
+ to_h['place']
40
+ end
41
+
42
+ def parent
43
+ Find.new(configuration: configuration)
44
+ .call(url: links.parent)
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'trailer_vote/api/configuration'
4
+
5
+ module TrailerVote
6
+ module Api
7
+ class Place
8
+ def initialize(configuration:)
9
+ self.configuration = configuration
10
+ end
11
+
12
+ private
13
+
14
+ attr_accessor :configuration
15
+ end
16
+ end
17
+ end
18
+
19
+ TrailerVote::MediaTypes::Place.register
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'trailer_vote/api/composable/common'
4
+
5
+ require 'trailer_vote/api/product'
6
+ require 'trailer_vote/api/product/find'
7
+
8
+ module TrailerVote
9
+ module Api
10
+ class Product
11
+
12
+ def create
13
+ Create.new(configuration: configuration)
14
+ end
15
+
16
+ class Create
17
+ include Composable::Common
18
+
19
+ CONTENT = MediaTypes::Product.to_constructable.version(2).view('create')
20
+ SUCCESS = MediaTypes::Product.to_constructable.version(2)
21
+ FAILURE = MediaTypes::Errors.to_constructable.version(1)
22
+
23
+ ACCEPT = [SUCCESS.to_s, FAILURE.to_s(0.1)].join(', ').freeze
24
+
25
+ def initialize(configuration:)
26
+ self.configuration = configuration
27
+ end
28
+
29
+ def call(data:, url: resolve_url)
30
+ body = encode(data)
31
+ branch(
32
+ resolve_client.headers(
33
+ Headers::ACCEPT => ACCEPT,
34
+ Headers::CONTENT_TYPE => "#{CONTENT}; charset=#{body.encoding.name}"
35
+ ).post(url, body: body),
36
+ data: data
37
+ )
38
+ end
39
+
40
+ private
41
+
42
+ def resolve_url
43
+ configuration.links.products
44
+ end
45
+
46
+ def encode(data)
47
+ TrailerVote::Api.encode(CONTENT, product: data)
48
+ end
49
+
50
+ def redirect_klazz
51
+ Find
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'trailer_vote/api/composable/get'
4
+ require 'trailer_vote/api/product'
5
+
6
+ module TrailerVote
7
+ module Api
8
+ class Product
9
+
10
+ def find(result: nil)
11
+ Find.new(configuration: configuration, result: result)
12
+ end
13
+
14
+ class Find
15
+ include Composable::Get
16
+
17
+ SUCCESS = MediaTypes::Product.to_constructable.version(2)
18
+ FAILURE = MediaTypes::Errors.to_constructable.version(1)
19
+ ACCEPT = [SUCCESS.to_s, FAILURE.to_s(0.1)].join(', ').freeze
20
+
21
+ def initialize(configuration:, result: nil)
22
+ self.configuration = configuration
23
+ self.result = result
24
+ end
25
+
26
+ def call(url: nil, data: nil)
27
+ return self if ok? || !url
28
+ branch(resolve_client.headers(Headers::ACCEPT => ACCEPT).get(url), data: data)
29
+ end
30
+
31
+ def data
32
+ to_h['product']
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'trailer_vote/api/composable/common'
4
+
5
+ require 'trailer_vote/api/product/image'
6
+ require 'trailer_vote/api/product/image/find'
7
+
8
+ module TrailerVote
9
+ module Api
10
+ class Product
11
+ class Image
12
+ def create
13
+ Create.new(configuration: configuration, product: product)
14
+ end
15
+
16
+ class Create
17
+ include Composable::Common
18
+
19
+ CONTENT = MediaTypes::ProductImage.to_constructable.version(1).view('create')
20
+ SUCCESS = MediaTypes::ProductImage.to_constructable.version(1)
21
+ FAILURE = MediaTypes::Errors.to_constructable.version(1)
22
+
23
+ ACCEPT = [SUCCESS.to_s, FAILURE.to_s(0.1)].join(', ').freeze
24
+
25
+ def initialize(configuration:, product:)
26
+ self.configuration = configuration
27
+ self.product = product
28
+ end
29
+
30
+ def call(data:, url: resolve_url)
31
+ body = encode(data)
32
+ branch(
33
+ resolve_client.headers(
34
+ Headers::ACCEPT => ACCEPT,
35
+ Headers::CONTENT_TYPE => "#{CONTENT}; charset=#{body.encoding.name}"
36
+ ).post(url, body: body),
37
+ data: data
38
+ )
39
+ end
40
+
41
+ private
42
+
43
+ attr_accessor :product
44
+
45
+ def resolve_url
46
+ product.links.images
47
+ end
48
+
49
+ def encode(data)
50
+ TrailerVote::Api.encode(CONTENT, product_image: data)
51
+ end
52
+
53
+ def forward(result, data:)
54
+ return unless [307, 308].include?(result.status)
55
+ forward_klazz.new(configuration: configuration, product: product)
56
+ .call(data: data, url: redirected_url(result))
57
+ end
58
+
59
+ def redirect_klazz
60
+ Find
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'trailer_vote/api/composable/get'
4
+ require 'trailer_vote/api/product/image'
5
+
6
+ module TrailerVote
7
+ module Api
8
+ class Product
9
+ class Image
10
+ def find(result: nil)
11
+ Find.new(configuration: configuration, result: result)
12
+ end
13
+
14
+ class Find
15
+ include Composable::Get
16
+
17
+ SUCCESS = MediaTypes::ProductImage.to_constructable.version(1)
18
+ FAILURE = MediaTypes::Errors.to_constructable.version(1)
19
+
20
+ ACCEPT = [SUCCESS.to_s, FAILURE.to_s(0.1)].join(', ').freeze
21
+
22
+ def initialize(configuration:, result: nil)
23
+ self.configuration = configuration
24
+ self.result = result
25
+ end
26
+
27
+ def call(url: nil)
28
+ return self if ok? || !url
29
+ branch(resolve_client.headers(Headers::ACCEPT => ACCEPT).get(url))
30
+ end
31
+
32
+ def data
33
+ to_h['product_image']
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'trailer_vote/api/composable/get'
4
+ require 'trailer_vote/api/product/image'
5
+
6
+ module TrailerVote
7
+ module Api
8
+ class Product
9
+ class Image
10
+ def urls
11
+ Urls.new(configuration: configuration, product: product)
12
+ end
13
+
14
+ class Urls
15
+ include Composable::Get
16
+
17
+ SUCCESS = MediaTypes::ProductImage.to_constructable.version(1).view('index')
18
+ FAILURE = MediaTypes::Errors.to_constructable.version(1)
19
+
20
+ ACCEPT = [SUCCESS.to_s, FAILURE.to_s(0.1)].join(', ').freeze
21
+
22
+ def initialize(configuration:, product:, result: nil)
23
+ self.configuration = configuration
24
+ self.product = product
25
+ self.result = result
26
+ end
27
+
28
+ def call(url: resolve_url)
29
+ return self if ok? || !url
30
+ branch(resolve_client.headers(Headers::ACCEPT => ACCEPT).get(url))
31
+ end
32
+
33
+ def data
34
+ to_h['product_images']
35
+ end
36
+
37
+ private
38
+
39
+ attr_accessor :product
40
+
41
+ def ok?
42
+ result&.status&.ok?
43
+ end
44
+
45
+ def resolve_url
46
+ product.links.images
47
+ end
48
+
49
+ def redirect(result)
50
+ redirect_klazz.new(configuration: configuration, product: product, result: result)
51
+ .call(url: redirected_url(result))
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'trailer_vote/api/product'
4
+ require 'trailer_vote/api/product/find'
5
+
6
+ module TrailerVote
7
+ module Api
8
+ class Product
9
+ class Find
10
+ def image
11
+ Image.new(configuration: configuration, product: self)
12
+ end
13
+
14
+ alias product_image image
15
+ end
16
+
17
+ class Image
18
+ def initialize(configuration:, product: nil)
19
+ self.configuration = configuration
20
+ self.product = product
21
+ end
22
+
23
+ private
24
+
25
+ attr_accessor :configuration, :product
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ TrailerVote::MediaTypes::ProductImage.register
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'trailer_vote/api/composable/common'
4
+
5
+ require 'trailer_vote/api/product'
6
+ require 'trailer_vote/api/product/find'
7
+
8
+ module TrailerVote
9
+ module Api
10
+ class Product
11
+
12
+ def lookup
13
+ Lookup.new(configuration: configuration)
14
+ end
15
+
16
+ ##
17
+ # Looks up a product by a set of authority and identifiers in +lookups+
18
+ #
19
+ # @example lookup a product by imdb or tmdb authority
20
+ #
21
+ # lookups = [
22
+ # { authority: 'imdb', identifier: 'tt1825683'},
23
+ # { authority: 'tmdb', identifier: '284054' }
24
+ # ]
25
+ # result = TrailerVote::Api.configure(...).product.lookup.call(data: lookups)
26
+ # result.product
27
+ # # => { "title": "" }
28
+ #
29
+ # @example try to lookup multiple products at the same time
30
+ #
31
+ # lookups = [
32
+ # { authority: 'imdb', identifier: 'tt1825683'},
33
+ # { authority: 'isbn', identifier: '978-1-59448-194-9' }
34
+ # ]
35
+ # result = TrailerVote::Api.configure(...).product.lookup.call(data: lookups)
36
+ # result.errors
37
+ # # => [{ "message": "Found multiple products for the given identifiers, only one result ..." }]
38
+ #
39
+ class Lookup
40
+ include Composable::Common
41
+
42
+ CONTENT = MediaTypes::ProductLookup.to_constructable.version(1)
43
+ SUCCESS = MediaTypes::Product.to_constructable.version(2)
44
+ FAILURE = MediaTypes::Errors.to_constructable.version(1)
45
+
46
+ ACCEPT = [SUCCESS.to_s, FAILURE.to_s(0.1)].join(', ').freeze
47
+
48
+ def initialize(configuration:)
49
+ self.configuration = configuration
50
+ end
51
+
52
+ def call(data:, url: resolve_url)
53
+ body = encode(data)
54
+ branch(
55
+ resolve_client.headers(
56
+ Headers::ACCEPT => ACCEPT,
57
+ Headers::CONTENT_TYPE => "#{CONTENT}; charset=#{body.encoding.name}"
58
+ ).post(url, body: body),
59
+ data: data
60
+ )
61
+ end
62
+
63
+ private
64
+
65
+ def resolve_url
66
+ configuration.links.product_lookup
67
+ end
68
+
69
+ def encode(data)
70
+ TrailerVote::Api.encode(CONTENT, product_identifiers: data)
71
+ end
72
+
73
+ def redirect_klazz
74
+ Find
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
80
+
81
+ TrailerVote::MediaTypes::ProductLookup.register
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'trailer_vote/api/composable/common'
4
+
5
+ require 'trailer_vote/api/product/place'
6
+ require 'trailer_vote/api/place/find'
7
+
8
+ module TrailerVote
9
+ module Api
10
+ class Product
11
+ class Place
12
+ def link
13
+ Link.new(configuration: configuration, product: product)
14
+ end
15
+
16
+ class Link
17
+ include Composable::Common
18
+
19
+ CONTENT = MediaTypes::ProductPlaceLink.to_constructable.version(1).view('create')
20
+ SUCCESS = MediaTypes::ProductPlaceLink.to_constructable.version(1)
21
+ FAILURE = MediaTypes::Errors.to_constructable.version(1)
22
+
23
+ ACCEPT = [SUCCESS.to_s, FAILURE.to_s(0.1)].join(', ').freeze
24
+
25
+ def initialize(configuration:, product:)
26
+ self.configuration = configuration
27
+ self.product = product
28
+ end
29
+
30
+ def call(data:, url: resolve_url)
31
+ body = encode(data)
32
+ branch(
33
+ resolve_client.headers(
34
+ Headers::ACCEPT => ACCEPT,
35
+ Headers::CONTENT_TYPE => "#{CONTENT}; charset=#{body.encoding.name}"
36
+ ).post(url, body: body),
37
+ data: data
38
+ )
39
+ end
40
+
41
+ private
42
+
43
+ def resolve_url
44
+ product.links.places
45
+ end
46
+
47
+ def encode(data)
48
+ TrailerVote::Api.encode(CONTENT, data.is_a?(::Hash) ? data : { place: data })
49
+ end
50
+
51
+ def forward(result, data:)
52
+ return unless [307, 308].include?(result.status)
53
+ forward_klazz.new(configuration: configuration, product: product)
54
+ .call(data: data, url: redirected_url(result))
55
+ end
56
+
57
+ def redirect_klazz
58
+ TrailerVote::Api::Place::Find
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'trailer_vote/api/product'
4
+ require 'trailer_vote/api/product/find'
5
+
6
+ module TrailerVote
7
+ module Api
8
+ class Product
9
+ class Find
10
+ def place
11
+ Place.new(configuration: configuration, product: self)
12
+ end
13
+
14
+ alias product_place place
15
+ end
16
+
17
+ class Place
18
+ def initialize(configuration:, product: nil)
19
+ self.configuration = configuration
20
+ self.product = product
21
+ end
22
+
23
+ private
24
+
25
+ attr_accessor :configuration, :product
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ TrailerVote::MediaTypes::ProductPlaceLink.register
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'trailer_vote/api/composable/common'
4
+
5
+ require 'trailer_vote/api/product'
6
+ require 'trailer_vote/api/product/find'
7
+
8
+ module TrailerVote
9
+ module Api
10
+ class Product
11
+ class Find
12
+ def update
13
+ Update.new(configuration: configuration, product: self)
14
+ end
15
+ end
16
+
17
+ class Update
18
+ include Composable::Common
19
+
20
+ CONTENT = MediaTypes::Product.to_constructable.version(2)
21
+ SUCCESS = MediaTypes::Product.to_constructable.version(2)
22
+ FAILURE = MediaTypes::Errors.to_constructable.version(1)
23
+
24
+ ACCEPT = [SUCCESS.to_s, FAILURE.to_s(0.1)].join(', ').freeze
25
+
26
+ def initialize(configuration:, product:)
27
+ self.configuration = configuration
28
+ self.product = product
29
+ end
30
+
31
+ def call(data:, url: resolve_url, etag: resolve_etag)
32
+ body = encode(data)
33
+ branch(
34
+ resolve_client.headers(
35
+ Headers::ACCEPT => ACCEPT,
36
+ Headers::CONTENT_TYPE => "#{CONTENT}; charset=#{body.encoding.name}",
37
+ Headers::IF_MATCH => etag
38
+ ).put(url, body: body),
39
+ data: data
40
+ )
41
+ end
42
+
43
+ private
44
+
45
+ attr_accessor :product
46
+
47
+ def resolve_url
48
+ product.links.self
49
+ end
50
+
51
+ def resolve_etag
52
+ product.etag
53
+ end
54
+
55
+ def encode(data)
56
+ TrailerVote::Api.encode(CONTENT, product: data)
57
+ end
58
+
59
+ def redirect_klazz
60
+ Find
61
+ end
62
+
63
+ def forward(result, data:)
64
+ return unless [307, 308].include?(result.status)
65
+ url = result['Location'] || result['Content-Location']
66
+ forward_klazz.new(configuration: configuration, product: product)
67
+ .call(data: data, url: url, etag: resolve_etag)
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end