trailer_vote-api 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
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