7digital 0.0.7 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (211) hide show
  1. data/README.rdoc +8 -1
  2. data/lib/sevendigital.rb +4 -2
  3. data/lib/sevendigital/api_operator.rb +92 -94
  4. data/lib/sevendigital/api_operator_cached.rb +55 -33
  5. data/lib/sevendigital/api_request.rb +50 -54
  6. data/lib/sevendigital/client.rb +15 -6
  7. data/lib/sevendigital/client_configuration.rb +0 -3
  8. data/lib/sevendigital/client_digestors.rb +15 -0
  9. data/lib/sevendigital/client_managers.rb +11 -1
  10. data/lib/sevendigital/digestion_tract/api_response_digestor.rb +31 -40
  11. data/lib/sevendigital/digestion_tract/artist_digestor.rb +16 -13
  12. data/lib/sevendigital/digestion_tract/basket_digestor.rb +5 -5
  13. data/lib/sevendigital/digestion_tract/basket_item_digestor.rb +12 -12
  14. data/lib/sevendigital/digestion_tract/chart_item_digestor.rb +17 -11
  15. data/lib/sevendigital/digestion_tract/country_digestor.rb +16 -0
  16. data/lib/sevendigital/digestion_tract/digestor.rb +82 -28
  17. data/lib/sevendigital/digestion_tract/download_url_digestor.rb +10 -7
  18. data/lib/sevendigital/digestion_tract/format_digestor.rb +11 -9
  19. data/lib/sevendigital/digestion_tract/label_digestor.rb +8 -7
  20. data/lib/sevendigital/digestion_tract/list_digestor.rb +24 -0
  21. data/lib/sevendigital/digestion_tract/list_item_digestor.rb +26 -0
  22. data/lib/sevendigital/digestion_tract/locker_digestor.rb +9 -5
  23. data/lib/sevendigital/digestion_tract/locker_release_digestor.rb +13 -7
  24. data/lib/sevendigital/digestion_tract/locker_track_digestor.rb +13 -9
  25. data/lib/sevendigital/digestion_tract/oauth_access_token_digestor.rb +7 -3
  26. data/lib/sevendigital/digestion_tract/oauth_request_token_digestor.rb +7 -3
  27. data/lib/sevendigital/digestion_tract/pager_digestor.rb +13 -9
  28. data/lib/sevendigital/digestion_tract/price_digestor.rb +15 -12
  29. data/lib/sevendigital/digestion_tract/release_digestor.rb +26 -34
  30. data/lib/sevendigital/digestion_tract/tag_digestor.rb +8 -7
  31. data/lib/sevendigital/digestion_tract/track_digestor.rb +27 -28
  32. data/lib/sevendigital/digestion_tract/user_card_digestor.rb +9 -8
  33. data/lib/sevendigital/digestion_tract/user_digestor.rb +8 -7
  34. data/lib/sevendigital/management/artist_manager.rb +9 -11
  35. data/lib/sevendigital/management/basket_manager.rb +4 -4
  36. data/lib/sevendigital/management/country_manager.rb +11 -0
  37. data/lib/sevendigital/management/list_manager.rb +18 -0
  38. data/lib/sevendigital/management/oauth_manager.rb +2 -2
  39. data/lib/sevendigital/management/release_manager.rb +9 -11
  40. data/lib/sevendigital/management/tag_manager.rb +1 -1
  41. data/lib/sevendigital/management/track_manager.rb +4 -5
  42. data/lib/sevendigital/management/user_card_manager.rb +2 -2
  43. data/lib/sevendigital/management/user_manager.rb +9 -4
  44. data/lib/sevendigital/model/api_response.rb +12 -4
  45. data/lib/sevendigital/model/artist.rb +5 -0
  46. data/lib/sevendigital/model/list.rb +5 -0
  47. data/lib/sevendigital/model/list_item.rb +9 -0
  48. data/lib/sevendigital/model/release.rb +2 -2
  49. data/lib/sevendigital/model/sevendigital_object.rb +1 -1
  50. data/lib/sevendigital/model/user.rb +12 -1
  51. data/lib/sevendigital/pager.rb +2 -6
  52. data/lib/sevendigital/version.rb +1 -1
  53. data/spec/api_operator_cached_spec.rb +14 -14
  54. data/spec/api_operator_spec.rb +18 -34
  55. data/spec/digestion_tract/api_response_digestor_spec.rb +26 -25
  56. data/spec/digestion_tract/artist_digestor_spec.rb +9 -9
  57. data/spec/digestion_tract/basket_digestor_spec.rb +2 -2
  58. data/spec/digestion_tract/basket_item_digestor_spec.rb +4 -4
  59. data/spec/digestion_tract/chart_digestor_spec.rb +4 -4
  60. data/spec/digestion_tract/country_digestor_spec.rb +33 -0
  61. data/spec/digestion_tract/digestor_spec.rb +34 -0
  62. data/spec/digestion_tract/download_url_digestor_spec.rb +2 -2
  63. data/spec/digestion_tract/format_digestor_spec.rb +2 -2
  64. data/spec/digestion_tract/label_digestor_spec.rb +2 -2
  65. data/spec/digestion_tract/list_digestor_spec.rb +32 -0
  66. data/spec/digestion_tract/list_item_digestor_spec.rb +80 -0
  67. data/spec/digestion_tract/locker_digestor_spec.rb +2 -2
  68. data/spec/digestion_tract/locker_release_digestor_spec.rb +5 -5
  69. data/spec/digestion_tract/locker_track_digestor_spec.rb +4 -4
  70. data/spec/digestion_tract/oauth_access_token_digestor_spec.rb +2 -2
  71. data/spec/digestion_tract/oauth_request_token_digestor_spec.rb +2 -2
  72. data/spec/digestion_tract/pager_digestor_spec.rb +3 -3
  73. data/spec/digestion_tract/price_digestor_spec.rb +4 -4
  74. data/spec/digestion_tract/release_digestor_spec.rb +19 -5
  75. data/spec/digestion_tract/tag_digestor_spec.rb +3 -3
  76. data/spec/digestion_tract/track_digestor_spec.rb +4 -4
  77. data/spec/digestion_tract/user_card_digestor_spec.rb +5 -5
  78. data/spec/digestion_tract/user_digestor_spec.rb +4 -6
  79. data/spec/integration/artist_spec.rb +86 -0
  80. data/spec/integration/country_spec.rb +18 -0
  81. data/spec/integration/list_spec.rb +22 -0
  82. data/spec/integration/purchasing_spec.rb +24 -0
  83. data/spec/integration/release_spec.rb +34 -0
  84. data/spec/integration/sevendigital_spec.yml +5 -0
  85. data/spec/integration/track_spec.rb +23 -0
  86. data/spec/integration/user_spec.rb +22 -0
  87. data/spec/management/artist_manager_spec.rb +32 -11
  88. data/spec/management/basket_manager_spec.rb +4 -4
  89. data/spec/management/country_manager_spec.rb +34 -0
  90. data/spec/management/list_manager_spec.rb +27 -0
  91. data/spec/management/oauth_manager_spec.rb +4 -4
  92. data/spec/management/release_manager_spec.rb +13 -13
  93. data/spec/management/tag_manager_spec.rb +1 -1
  94. data/spec/management/track_manager_spec.rb +4 -4
  95. data/spec/management/user_card_manager_spec.rb +2 -2
  96. data/spec/management/user_manager_spec.rb +20 -4
  97. data/spec/model/api_response_spec.rb +3 -3
  98. data/spec/model/artist_spec.rb +2 -2
  99. data/spec/model/sevendigital_object_spec.rb +4 -4
  100. data/spec/model/user_spec.rb +21 -0
  101. data/spec/spec_helper.rb +31 -11
  102. data/spec/test-xml/methods/country/resolve.xml +7 -0
  103. data/spec/test-xml/methods/editorial/list.xml +171 -0
  104. data/spec/test-xml/methods/user/details.xml +5 -0
  105. data/spec/test-xml/objects/artist.xml +1 -0
  106. data/spec/test-xml/objects/list.xml +89 -0
  107. data/spec/test-xml/objects/list_item_list.xml +86 -0
  108. data/spec/test-xml/objects/list_item_release.xml +14 -0
  109. data/spec/test-xml/objects/nested_release_list.xml +23 -0
  110. metadata +126 -273
  111. data/lib/sevendigital/peachy_patchy.rb +0 -9
  112. data/lib/sevendigital/proxy_police.rb +0 -28
  113. data/spec/coverage/assets/0.3.9/app.js +0 -66
  114. data/spec/coverage/assets/0.3.9/fancybox/blank.gif +0 -0
  115. data/spec/coverage/assets/0.3.9/fancybox/fancy_close.png +0 -0
  116. data/spec/coverage/assets/0.3.9/fancybox/fancy_loading.png +0 -0
  117. data/spec/coverage/assets/0.3.9/fancybox/fancy_nav_left.png +0 -0
  118. data/spec/coverage/assets/0.3.9/fancybox/fancy_nav_right.png +0 -0
  119. data/spec/coverage/assets/0.3.9/fancybox/fancy_shadow_e.png +0 -0
  120. data/spec/coverage/assets/0.3.9/fancybox/fancy_shadow_n.png +0 -0
  121. data/spec/coverage/assets/0.3.9/fancybox/fancy_shadow_ne.png +0 -0
  122. data/spec/coverage/assets/0.3.9/fancybox/fancy_shadow_nw.png +0 -0
  123. data/spec/coverage/assets/0.3.9/fancybox/fancy_shadow_s.png +0 -0
  124. data/spec/coverage/assets/0.3.9/fancybox/fancy_shadow_se.png +0 -0
  125. data/spec/coverage/assets/0.3.9/fancybox/fancy_shadow_sw.png +0 -0
  126. data/spec/coverage/assets/0.3.9/fancybox/fancy_shadow_w.png +0 -0
  127. data/spec/coverage/assets/0.3.9/fancybox/fancy_title_left.png +0 -0
  128. data/spec/coverage/assets/0.3.9/fancybox/fancy_title_main.png +0 -0
  129. data/spec/coverage/assets/0.3.9/fancybox/fancy_title_over.png +0 -0
  130. data/spec/coverage/assets/0.3.9/fancybox/fancy_title_right.png +0 -0
  131. data/spec/coverage/assets/0.3.9/fancybox/fancybox-x.png +0 -0
  132. data/spec/coverage/assets/0.3.9/fancybox/fancybox-y.png +0 -0
  133. data/spec/coverage/assets/0.3.9/fancybox/fancybox.png +0 -0
  134. data/spec/coverage/assets/0.3.9/fancybox/jquery.fancybox-1.3.1.css +0 -363
  135. data/spec/coverage/assets/0.3.9/fancybox/jquery.fancybox-1.3.1.pack.js +0 -44
  136. data/spec/coverage/assets/0.3.9/favicon.png +0 -0
  137. data/spec/coverage/assets/0.3.9/jquery-1.4.2.min.js +0 -155
  138. data/spec/coverage/assets/0.3.9/jquery.dataTables.min.js +0 -152
  139. data/spec/coverage/assets/0.3.9/jquery.timeago.js +0 -141
  140. data/spec/coverage/assets/0.3.9/jquery.url.js +0 -174
  141. data/spec/coverage/assets/0.3.9/loading.gif +0 -0
  142. data/spec/coverage/assets/0.3.9/magnify.png +0 -0
  143. data/spec/coverage/assets/0.3.9/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  144. data/spec/coverage/assets/0.3.9/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  145. data/spec/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  146. data/spec/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  147. data/spec/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  148. data/spec/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  149. data/spec/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  150. data/spec/coverage/assets/0.3.9/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  151. data/spec/coverage/assets/0.3.9/smoothness/images/ui-icons_222222_256x240.png +0 -0
  152. data/spec/coverage/assets/0.3.9/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  153. data/spec/coverage/assets/0.3.9/smoothness/images/ui-icons_454545_256x240.png +0 -0
  154. data/spec/coverage/assets/0.3.9/smoothness/images/ui-icons_888888_256x240.png +0 -0
  155. data/spec/coverage/assets/0.3.9/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  156. data/spec/coverage/assets/0.3.9/smoothness/jquery-ui-1.8.4.custom.css +0 -295
  157. data/spec/coverage/assets/0.3.9/stylesheet.css +0 -341
  158. data/spec/coverage/index.html +0 -47481
  159. data/spec/coverage/resultset.yml +0 -3556
  160. data/spec/model/coverage/assets/0.3.9/app.js +0 -66
  161. data/spec/model/coverage/assets/0.3.9/fancybox/blank.gif +0 -0
  162. data/spec/model/coverage/assets/0.3.9/fancybox/fancy_close.png +0 -0
  163. data/spec/model/coverage/assets/0.3.9/fancybox/fancy_loading.png +0 -0
  164. data/spec/model/coverage/assets/0.3.9/fancybox/fancy_nav_left.png +0 -0
  165. data/spec/model/coverage/assets/0.3.9/fancybox/fancy_nav_right.png +0 -0
  166. data/spec/model/coverage/assets/0.3.9/fancybox/fancy_shadow_e.png +0 -0
  167. data/spec/model/coverage/assets/0.3.9/fancybox/fancy_shadow_n.png +0 -0
  168. data/spec/model/coverage/assets/0.3.9/fancybox/fancy_shadow_ne.png +0 -0
  169. data/spec/model/coverage/assets/0.3.9/fancybox/fancy_shadow_nw.png +0 -0
  170. data/spec/model/coverage/assets/0.3.9/fancybox/fancy_shadow_s.png +0 -0
  171. data/spec/model/coverage/assets/0.3.9/fancybox/fancy_shadow_se.png +0 -0
  172. data/spec/model/coverage/assets/0.3.9/fancybox/fancy_shadow_sw.png +0 -0
  173. data/spec/model/coverage/assets/0.3.9/fancybox/fancy_shadow_w.png +0 -0
  174. data/spec/model/coverage/assets/0.3.9/fancybox/fancy_title_left.png +0 -0
  175. data/spec/model/coverage/assets/0.3.9/fancybox/fancy_title_main.png +0 -0
  176. data/spec/model/coverage/assets/0.3.9/fancybox/fancy_title_over.png +0 -0
  177. data/spec/model/coverage/assets/0.3.9/fancybox/fancy_title_right.png +0 -0
  178. data/spec/model/coverage/assets/0.3.9/fancybox/fancybox-x.png +0 -0
  179. data/spec/model/coverage/assets/0.3.9/fancybox/fancybox-y.png +0 -0
  180. data/spec/model/coverage/assets/0.3.9/fancybox/fancybox.png +0 -0
  181. data/spec/model/coverage/assets/0.3.9/fancybox/jquery.fancybox-1.3.1.css +0 -363
  182. data/spec/model/coverage/assets/0.3.9/fancybox/jquery.fancybox-1.3.1.pack.js +0 -44
  183. data/spec/model/coverage/assets/0.3.9/favicon.png +0 -0
  184. data/spec/model/coverage/assets/0.3.9/jquery-1.4.2.min.js +0 -155
  185. data/spec/model/coverage/assets/0.3.9/jquery.dataTables.min.js +0 -152
  186. data/spec/model/coverage/assets/0.3.9/jquery.timeago.js +0 -141
  187. data/spec/model/coverage/assets/0.3.9/jquery.url.js +0 -174
  188. data/spec/model/coverage/assets/0.3.9/loading.gif +0 -0
  189. data/spec/model/coverage/assets/0.3.9/magnify.png +0 -0
  190. data/spec/model/coverage/assets/0.3.9/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  191. data/spec/model/coverage/assets/0.3.9/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  192. data/spec/model/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  193. data/spec/model/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  194. data/spec/model/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  195. data/spec/model/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  196. data/spec/model/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  197. data/spec/model/coverage/assets/0.3.9/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  198. data/spec/model/coverage/assets/0.3.9/smoothness/images/ui-icons_222222_256x240.png +0 -0
  199. data/spec/model/coverage/assets/0.3.9/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  200. data/spec/model/coverage/assets/0.3.9/smoothness/images/ui-icons_454545_256x240.png +0 -0
  201. data/spec/model/coverage/assets/0.3.9/smoothness/images/ui-icons_888888_256x240.png +0 -0
  202. data/spec/model/coverage/assets/0.3.9/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  203. data/spec/model/coverage/assets/0.3.9/smoothness/jquery-ui-1.8.4.custom.css +0 -295
  204. data/spec/model/coverage/assets/0.3.9/stylesheet.css +0 -341
  205. data/spec/model/coverage/index.html +0 -8637
  206. data/spec/model/coverage/resultset.yml +0 -642
  207. data/spec/pager_spec.rb +0 -7
  208. data/spec/peachy_spec_helper_patch.rb +0 -7
  209. data/spec/proxy_police_spec.rb +0 -70
  210. data/spec/sevendigital_spec.rb +0 -51
  211. data/spec/sevendigital_spec.yml +0 -5
@@ -4,22 +4,29 @@ This is a ruby wrapper for the 7digital API.
4
4
 
5
5
  ==About 7digital
6
6
 
7
- 7digital.com is an online music store operating in over 16 countries and offering more than 11 million high quality DRM free MP3s (320kbps) from all major labels and wide range of idependent labels and distributors. 7digital API will give you access to the full catalogue including high quality album art, 30s preview clips for all tracks, commissions on sales, integrated purchasing and full length streaming. More details at http://developer.7digital.net
7
+ 7digital.com is an online music store operating in over 30 countries and offering more than 20 million high quality DRM free MP3s (320kbps) from all major labels and wide range of idependent labels and distributors. 7digital API will give you access to the full catalogue including high quality album art, 30s preview clips for all tracks, commissions on sales, integrated purchasing and full length streaming. More details at http://developer.7digital.net
8
8
 
9
9
  ==Installation
10
10
 
11
11
  gem install 7digital
12
12
 
13
+
13
14
  ==Quick start example
14
15
 
15
16
 
16
17
  require "sevendigital"
18
+
17
19
  api_client = Sevendigital::Client.new(:oauth_consumer_key => "YOUR_KEY_HERE", :country => "GB")
20
+
18
21
  an_artist = api_client.artist.search("radiohead").first
22
+
19
23
  a_release = an_artist.releases(:page_size=>100).sort_by{|release| release.year}.last
24
+
20
25
  puts "the latest #{an_artist.name} release is #{a_release.title} from #{a_release.year}"
26
+
21
27
  puts "go and buy it at #{a_release.url} !"
22
28
 
29
+
23
30
  ==Usage details
24
31
 
25
32
  ===Initializing & configuring an API Client
@@ -43,8 +43,10 @@ module Sevendigital
43
43
 
44
44
  end # module 7digital
45
45
 
46
- require 'peachy'
47
- Peachy.be_quiet
46
+ require 'nokogiri'
47
+ require 'bigdecimal'
48
+ require 'bigdecimal/util'
49
+ require 'logger'
48
50
  require File.join( File.dirname( File.expand_path(__FILE__)), 'sevendigital', 'client_configuration')
49
51
  require File.join( File.dirname( File.expand_path(__FILE__)), 'sevendigital', 'management', 'manager')
50
52
  require File.join( File.dirname( File.expand_path(__FILE__)), 'sevendigital', 'digestion_tract', 'digestor')
@@ -11,121 +11,119 @@ module Sevendigital
11
11
  #deals with OAuth signing requests that require signature, making sure parameters are in correct format etc
12
12
  class ApiOperator # :nodoc:
13
13
 
14
- RESERVED_CHARACTERS = /[^a-zA-Z0-9\-\.\_\~]/
14
+ RESERVED_CHARACTERS = /[^a-zA-Z0-9\-\.\_\~]/
15
15
 
16
- def initialize(client)
17
- @client = client
18
- end
16
+ def initialize(client)
17
+ @client = client
18
+ end
19
19
 
20
- def call_api(api_request)
21
- api_response = make_http_request_and_digest(api_request)
22
- puts api_response.content.to_s if @client.very_verbose?
23
- api_response
24
- end
20
+ def call_api(api_request)
21
+ make_http_request_and_digest(api_request).tap do |api_response|
22
+ @client.log(:verbose) { "ApiOperator: API Response: #{api_response}" }
23
+ end
24
+ end
25
25
 
26
- def get_request_uri(api_request)
27
- api_request.signature_scheme = :query_string if api_request.requires_signature?
28
- http_client, http_request = create_http_request(api_request)
29
- path = http_request.instance_variable_get("@path")
30
- host = http_client.instance_variable_get("@address")
31
- port = http_client.instance_variable_get("@port")
32
- scheme = port == 443 ? "https" : "http"
33
- return "#{scheme}://#{host}#{path}"
34
- end
26
+ def get_request_uri(api_request)
27
+ api_request.signature_scheme = :query_string if api_request.requires_signature?
28
+ http_client, http_request = create_http_request(api_request)
29
+ path = http_request.instance_variable_get("@path")
30
+ host = http_client.instance_variable_get("@address")
31
+ port = http_client.instance_variable_get("@port")
32
+ scheme = port == 443 ? "https" : "http"
33
+ "#{scheme}://#{host}#{path}"
34
+ end
35
35
 
36
- def make_http_request_and_digest(api_request)
36
+ def make_http_request_and_digest(api_request)
37
37
  digest_http_response(make_http_request(api_request))
38
- end
39
-
40
- def make_http_request(api_request)
41
-
42
- http_client, http_request = create_http_request(api_request)
43
-
44
- http_client.set_debug_output($stdout) if @client.very_verbose?
45
- log_request(http_request) if @client.verbose?
38
+ end
46
39
 
47
- http_client.request(http_request)
48
- end
40
+ def make_http_request(api_request)
41
+ http_client, http_request = create_http_request(api_request)
42
+ @client.log(:verbose) { "ApiOperator: Making HTTP Request..." }
43
+ http_client.request(http_request).tap do |http_response|
44
+ puts @client.inspect
45
+ puts http_response.inspect
46
+ @client.log(:verbose) { "ApiOperator: Response Headers: #{http_response.header.to_yaml}" }
47
+ end
48
+ end
49
49
 
50
- def digest_http_response(http_response)
51
- api_response = @client.api_response_digestor.from_http_response(http_response)
52
- raise Sevendigital::SevendigitalError.new(api_response.error_code, api_response.error_message), "#{api_response.error_code} - #{api_response.error_message}" if !api_response.ok?
53
- api_response
54
- end
50
+ def digest_http_response(http_response)
51
+ @client.api_response_digestor.from_http_response(http_response).tap do |api_response|
52
+ unless api_response.ok?
53
+ raise Sevendigital::SevendigitalError.new(api_response.error_code, api_response.error_message), "#{api_response.error_code} - #{api_response.error_message}"
54
+ end
55
+ end
56
+ end
55
57
 
56
- def create_http_request(api_request)
57
- http_client, http_request = create_standard_http_request(api_request)
58
- if (api_request.requires_signature?) then
59
- oauth_sign_request(http_client, http_request, api_request)
60
- else
58
+ def create_http_request(api_request)
59
+ http_client, http_request = create_standard_http_request(api_request)
60
+ if (api_request.requires_signature?)
61
+ oauth_sign_request(http_client, http_request, api_request)
62
+ else
63
+ end
64
+ [http_client, http_request]
61
65
  end
62
- return http_client, http_request
63
- end
64
66
 
65
- def oauth_sign_request(http_client, http_request, api_request)
66
- http_request.oauth!( \
67
- http_client, \
68
- @client.oauth_consumer, \
69
- api_request.token, \
70
- {:scheme => api_request.signature_scheme}
71
- )
72
- return http_request
73
- end
67
+ def oauth_sign_request(http_client, http_request, api_request)
68
+ http_request.oauth!( \
69
+ http_client, \
70
+ @client.oauth_consumer, \
71
+ api_request.token, \
72
+ {:scheme => api_request.signature_scheme}
73
+ )
74
+ http_request
75
+ end
74
76
 
75
- def create_standard_http_request(api_request)
76
- request_uri = create_request_uri(api_request)
77
- http_client = Net::HTTP.new(request_uri.host, request_uri.port)
77
+ def create_standard_http_request(api_request)
78
+ request_uri = create_request_uri(api_request)
79
+ http_client = Net::HTTP.new(request_uri.host, request_uri.port)
78
80
 
79
- if !api_request.requires_signature? then
80
- request_uri.query ||= ""
81
- request_uri.query += "&oauth_consumer_key=#{@client.configuration.oauth_consumer_key}"
82
- end
81
+ if !api_request.requires_signature?
82
+ request_uri.query ||= ""
83
+ request_uri.query += "&oauth_consumer_key=#{@client.configuration.oauth_consumer_key}"
84
+ end
83
85
 
84
- http_request = new_http_request(request_uri.request_uri, api_request.http_method)
86
+ http_request = new_http_request(request_uri.request_uri, api_request.http_method)
85
87
 
86
- ensure_secure_connection(http_client) if api_request.requires_secure_connection?
87
- add_form_parameters(http_request, api_request)
88
+ ensure_secure_connection(http_client) if api_request.requires_secure_connection?
89
+ add_form_parameters(http_request, api_request)
88
90
 
89
- return http_client, http_request
90
- end
91
+ @client.log(:verbose) { "ApiOperator: Creating HTTP Request: #{request_uri}" }
91
92
 
92
- def ensure_secure_connection(http_client)
93
- http_client.use_ssl = true
94
- http_client.verify_mode = OpenSSL::SSL::VERIFY_NONE
95
- end
93
+ [http_client, http_request]
94
+ end
96
95
 
97
- def create_request_uri(api_request)
98
- host, version = @client.api_host_and_version(api_request.api_service)
99
- path = "/#{version}/#{api_request.api_method}"
100
- query = api_request.parameters.map{ |k,v| "#{escape(k)}=#{escape(v)}" }.join("&")
101
- query = nil if query == ""
102
- if api_request.requires_secure_connection? then
103
- URI::HTTPS.build(:host => host, :path => path, :query =>query)
104
- else
105
- URI::HTTP.build(:host => host, :path => path, :query =>query)
96
+ def ensure_secure_connection(http_client)
97
+ http_client.use_ssl = true
98
+ http_client.verify_mode = OpenSSL::SSL::VERIFY_NONE
106
99
  end
107
- end
108
100
 
109
- def new_http_request(request_uri, http_method)
110
- request_type = Kernel.const_get("Net").const_get("HTTP").const_get(http_method.to_s.capitalize)
111
- request_type.new(request_uri, {"user-agent" => @client.user_agent_info})
112
- end
101
+ def create_request_uri(api_request)
102
+ host, version = @client.api_host_and_version(api_request.api_service)
103
+ path = "/#{version}/#{api_request.api_method}"
104
+ query = api_request.parameters.map{ |k,v| "#{escape(k)}=#{escape(v)}" }.join("&")
105
+ query = nil if query == ""
106
+ if api_request.requires_secure_connection? then
107
+ URI::HTTPS.build(:host => host, :path => path, :query =>query)
108
+ else
109
+ URI::HTTP.build(:host => host, :path => path, :query =>query)
110
+ end
111
+ end
113
112
 
114
- def add_form_parameters(http_request, api_request)
115
- http_request.body = api_request.form_parameters.map {|k, v| "#{escape(k)}=#{escape(v)}" }.flatten.join('&')
116
- http_request.content_type = 'application/x-www-form-urlencoded'
117
- end
113
+ def new_http_request(request_uri, http_method)
114
+ request_type = Kernel.const_get("Net").const_get("HTTP").const_get(http_method.to_s.capitalize)
115
+ request_type.new(request_uri, {"user-agent" => @client.user_agent_info})
116
+ end
118
117
 
119
- def escape(value)
120
- URI::escape(value.to_s, RESERVED_CHARACTERS)
121
- rescue ArgumentError
122
- URI::escape(value.to_s.force_encoding(Encoding::UTF_8), RESERVED_CHARACTERS)
123
- end
118
+ def add_form_parameters(http_request, api_request)
119
+ http_request.body = api_request.form_parameters.map {|k, v| "#{escape(k)}=#{escape(v)}" }.flatten.join('&')
120
+ http_request.content_type = 'application/x-www-form-urlencoded'
121
+ end
124
122
 
125
- def log_request(request)
126
- puts "ApiOperator calling #{request.inspect}" if @client.verbose?
123
+ def escape(value)
124
+ URI::escape(value.to_s, RESERVED_CHARACTERS)
125
+ rescue ArgumentError
126
+ URI::escape(value.to_s.force_encoding(Encoding::UTF_8), RESERVED_CHARACTERS)
127
+ end
127
128
  end
128
-
129
129
  end
130
-
131
- end
@@ -1,41 +1,63 @@
1
1
  module Sevendigital
2
+ #@private
3
+ #Cached version of ApiOperator
4
+ #If response for an API request is already in cache and
5
+ #and it hasn't expired returns the cached response is returned instead of making an API call
6
+ #otherwise uses methods inherited from ApiOperator to make an HTTP call to the API
7
+ class ApiOperatorCached < ApiOperator # :nodoc:
8
+ def initialize(client, cache)
9
+ @cache = cache
10
+ super(client)
11
+ end
2
12
 
3
- #@private
4
- #Cached version of ApiOperator
5
- #If response for an API request is already in cache and
6
- #and it hasn't expired returns the cached response is returned instead of making an API call
7
- #otherwise uses methods inherited from ApiOperator to make an HTTP call to the API
8
- class ApiOperatorCached < ApiOperator # :nodoc:
13
+ def call_api(api_request)
14
+ api_response = retrieve_from_cache(api_request)
15
+ api_response = cache_response(api_request) if response_out_of_date?(api_response)
9
16
 
10
- def initialize(client, cache)
11
- @cache = cache
12
- super(client)
13
- end
17
+ api_response.tap do |api_response|
18
+ @client.log(:verbose) { "ApiOperatorCached: API Response: #{api_response}" }
19
+ end
20
+ end
14
21
 
15
- def call_api(api_request)
16
- request_cache_key = create_request_uri(api_request)
17
- http_response = @cache.get(request_cache_key.to_s) if !api_request.requires_signature?
18
- puts "ApiOperatorCached: Got from cache #{request_cache_key}" if @client.verbose? && http_response
19
- puts "but the response is out of date" if @client.verbose? && http_response && response_out_of_date?(http_response)
20
- if (!http_response || response_out_of_date?(http_response)) then
21
- http_response = make_http_request(api_request)
22
- @cache.set(request_cache_key.to_s, http_response) if !api_request.requires_signature?
23
- end
24
- api_response = digest_http_response(http_response)
25
- p api_response if @client.very_verbose?
26
- api_response
27
- end
28
22
 
29
- def response_out_of_date?(http_response, current_time=nil)
30
- return true if http_response.header.nil? || http_response.header["Date"].nil? || http_response.header["cache-control"].nil?
31
- puts "cache headers present"
32
- return true if !(http_response.header["cache-control"] =~ /max-age=([0-9]+)/)
33
- current_time ||= Time.now.utc
34
- response_time = Time.parse(http_response.header["Date"])
35
- max_age = /max-age=([0-9]+)/.match(http_response.header["cache-control"])[1].to_i
36
- response_time + max_age < current_time
37
- end
23
+ def response_out_of_date?(api_response, current_time=nil)
24
+ puts @client.inspect
25
+ (api_response.nil? || header_invalid?(api_response.headers) || cache_expired?(api_response.headers, current_time)).tap do |expired|
26
+ @client.log(:verbose) { "ApiOperatorCached: Cache response out of date" if expired }
27
+ end
28
+ end
38
29
 
39
- end
30
+ private
31
+
32
+ def header_invalid?(header)
33
+ header["Date"].nil? || header["cache-control"].nil? || !(header["cache-control"] =~ /max-age=([0-9]+)/)
34
+ end
40
35
 
36
+ def cache_expired?(header, current_time=nil)
37
+ (Time.parse(header["Date"]) + (/max-age=([0-9]+)/.match(header["cache-control"])[1].to_i)) < (current_time || Time.now.utc)
38
+ end
39
+
40
+ def cache_response(api_request)
41
+ digest_http_response(make_http_request(api_request)).tap do |api_response|
42
+ unless api_request.requires_signature?
43
+ key = request_cache_key(api_request)
44
+ @cache.respond_to?(:write) ? @cache.write(key, api_response) : @cache.set(key, api_response)
45
+ @client.log(:verbose) { "ApiOperatorCached: Storing response in cache..." }
46
+ end
47
+ end
48
+ end
49
+
50
+ def request_cache_key(api_request)
51
+ create_request_uri(api_request).to_s
52
+ end
53
+
54
+ def retrieve_from_cache(api_request)
55
+ unless api_request.requires_signature?
56
+ key = request_cache_key(api_request)
57
+ (@cache.respond_to?(:read) ? @cache.read(key) : @cache.get(key)).tap do |response|
58
+ @client.log(:verbose) { "ApiOperatorCached: Got from cache #{key}" if response }
59
+ end
60
+ end
61
+ end
62
+ end
41
63
  end
@@ -1,66 +1,62 @@
1
1
  module Sevendigital
2
+ #@private
3
+ #Abstraction of a HTTP API request, ApiOperator uses this ApiRequest to build a real HTTP requests
4
+ class ApiRequest # :nodoc:
5
+
6
+ attr_reader :api_method, :parameters, :signed
7
+ attr_accessor :token, :api_service, :http_method
8
+ attr_accessor :signature_scheme
9
+ attr_writer :form_parameters
10
+
11
+ def initialize(http_method, api_method, parameters, options={})
12
+ @api_method = api_method
13
+ @parameters = parameters
14
+ @signature_scheme = :header
15
+ @http_method = http_method
16
+ comb_parameters(parameters)
17
+ @form_parameters = Hash.new
18
+ end
2
19
 
3
- #@private
4
- #Abstraction of a HTTP API request, ApiOperator uses this ApiRequest to build a real HTTP requests
5
- class ApiRequest # :nodoc:
6
-
7
- attr_reader :api_method, :parameters, :signed
8
- attr_accessor :token, :api_service, :http_method
9
- attr_accessor :signature_scheme
10
- attr_writer :form_parameters
11
-
12
- def initialize(http_method, api_method, parameters, options={})
13
- @api_method = api_method
14
- @parameters = parameters
15
- @signature_scheme = :header
16
- @http_method = http_method
17
- comb_parameters(parameters)
18
- @form_parameters = Hash.new
19
- end
20
-
21
- def form_parameters
22
- comb_parameters(@form_parameters)
23
- end
20
+ def form_parameters
21
+ comb_parameters(@form_parameters)
22
+ end
24
23
 
25
- def requires_signature?
26
- @signed == true
27
- end
24
+ def requires_signature?
25
+ @signed == true
26
+ end
28
27
 
29
- def require_signature
30
- @signed = true
31
- end
28
+ def require_signature
29
+ @signed = true
30
+ end
32
31
 
33
- def requires_secure_connection?
34
- @secure == true
35
- end
32
+ def requires_secure_connection?
33
+ @secure == true
34
+ end
36
35
 
37
- def require_secure_connection
38
- @secure = true
39
- end
36
+ def require_secure_connection
37
+ @secure = true
38
+ end
40
39
 
41
- def comb_parameters(parameters)
42
- comb_parameter(parameters, :pageSize, [:page_size, :per_page])
43
- comb_parameter(parameters, :shopId, :shop_id)
44
- comb_parameter(parameters, :imageSize, :image_size)
45
- remove_empty_parameters(parameters)
46
- parameters
47
- end
40
+ def comb_parameters(parameters)
41
+ comb_parameter(parameters, :pageSize, [:page_size, :per_page])
42
+ comb_parameter(parameters, :shopId, :shop_id)
43
+ comb_parameter(parameters, :imageSize, :image_size)
44
+ remove_empty_parameters(parameters)
45
+ parameters
46
+ end
48
47
 
49
- def comb_parameter(parameters, correct_name, alternative_names)
50
- param_value = nil
51
- alternative_names = [alternative_names] unless alternative_names.is_a?(Array)
52
- alternative_names.each do |alternative_name|
53
- param_value ||= parameters[alternative_name]
54
- parameters.delete(alternative_name)
48
+ def comb_parameter(parameters, correct_name, alternative_names)
49
+ param_value = nil
50
+ alternative_names = [alternative_names] unless alternative_names.is_a?(Array)
51
+ alternative_names.each do |alternative_name|
52
+ param_value ||= parameters[alternative_name]
53
+ parameters.delete(alternative_name)
54
+ end
55
+ parameters[correct_name] ||= param_value if param_value
55
56
  end
56
- parameters[correct_name] ||= param_value if param_value
57
- end
58
57
 
59
- def remove_empty_parameters(parameters)
60
- parameters.delete_if { |key, value| value.nil? }
58
+ def remove_empty_parameters(parameters)
59
+ parameters.delete_if { |key, value| value.nil? }
60
+ end
61
61
  end
62
-
63
-
64
62
  end
65
-
66
- end