7digital 0.0.2 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +132 -5
- data/lib/sevendigital.rb +1 -2
- data/lib/sevendigital/api_operator.rb +103 -12
- data/lib/sevendigital/api_operator_cached.rb +14 -8
- data/lib/sevendigital/api_request.rb +50 -9
- data/lib/sevendigital/client.rb +51 -89
- data/lib/sevendigital/client_configuration.rb +86 -0
- data/lib/sevendigital/client_digestors.rb +79 -0
- data/lib/sevendigital/client_managers.rb +34 -0
- data/lib/sevendigital/digestion_tract/api_response_digestor.rb +8 -3
- data/lib/sevendigital/digestion_tract/artist_digestor.rb +1 -1
- data/lib/sevendigital/digestion_tract/basket_digestor.rb +18 -0
- data/lib/sevendigital/digestion_tract/basket_item_digestor.rb +25 -0
- data/lib/sevendigital/digestion_tract/chart_item_digestor.rb +1 -1
- data/lib/sevendigital/digestion_tract/digestor.rb +7 -3
- data/lib/sevendigital/digestion_tract/download_url_digestor.rb +19 -0
- data/lib/sevendigital/digestion_tract/format_digestor.rb +1 -1
- data/lib/sevendigital/digestion_tract/label_digestor.rb +1 -1
- data/lib/sevendigital/digestion_tract/locker_digestor.rb +17 -0
- data/lib/sevendigital/digestion_tract/locker_release_digestor.rb +19 -0
- data/lib/sevendigital/digestion_tract/locker_track_digestor.rb +21 -0
- data/lib/sevendigital/digestion_tract/oauth_access_token_digestor.rb +14 -0
- data/lib/sevendigital/digestion_tract/oauth_request_token_digestor.rb +14 -0
- data/lib/sevendigital/digestion_tract/pager_digestor.rb +1 -1
- data/lib/sevendigital/digestion_tract/price_digestor.rb +3 -3
- data/lib/sevendigital/digestion_tract/release_digestor.rb +1 -1
- data/lib/sevendigital/digestion_tract/tag_digestor.rb +22 -0
- data/lib/sevendigital/digestion_tract/track_digestor.rb +1 -1
- data/lib/sevendigital/management/artist_manager.rb +71 -34
- data/lib/sevendigital/management/basket_manager.rb +29 -0
- data/lib/sevendigital/management/manager.rb +1 -1
- data/lib/sevendigital/management/oauth_manager.rb +23 -0
- data/lib/sevendigital/management/release_manager.rb +7 -14
- data/lib/sevendigital/management/tag_manager.rb +11 -0
- data/lib/sevendigital/management/track_manager.rb +9 -9
- data/lib/sevendigital/management/user_manager.rb +51 -0
- data/lib/sevendigital/model/api_response.rb +19 -3
- data/lib/sevendigital/model/artist.rb +27 -9
- data/lib/sevendigital/model/basket.rb +16 -0
- data/lib/sevendigital/model/basket_item.rb +15 -0
- data/lib/sevendigital/model/download_url.rb +7 -0
- data/lib/sevendigital/model/format.rb +0 -2
- data/lib/sevendigital/model/label.rb +1 -3
- data/lib/sevendigital/model/locker.rb +5 -0
- data/lib/sevendigital/model/locker_release.rb +9 -0
- data/lib/sevendigital/model/locker_track.rb +9 -0
- data/lib/sevendigital/model/price.rb +0 -2
- data/lib/sevendigital/model/release.rb +22 -8
- data/lib/sevendigital/model/sevendigital_error.rb +9 -1
- data/lib/sevendigital/model/sevendigital_object.rb +16 -11
- data/lib/sevendigital/model/tag.rb +7 -0
- data/lib/sevendigital/model/track.rb +4 -4
- data/lib/sevendigital/model/user.rb +34 -0
- data/lib/sevendigital/pager.rb +8 -2
- data/lib/sevendigital/proxy_police.rb +5 -1
- data/lib/sevendigital/version.rb +5 -0
- data/spec/api_operator_cached_spec.rb +62 -7
- data/spec/api_operator_spec.rb +245 -21
- data/spec/api_request_spec.rb +20 -15
- data/spec/client_configuration_spec.rb +75 -0
- data/spec/client_spec.rb +126 -48
- data/spec/coverage/assets/0.3.9/app.js +66 -0
- data/spec/coverage/assets/0.3.9/fancybox/blank.gif +0 -0
- data/spec/coverage/assets/0.3.9/fancybox/fancy_close.png +0 -0
- data/spec/coverage/assets/0.3.9/fancybox/fancy_loading.png +0 -0
- data/spec/coverage/assets/0.3.9/fancybox/fancy_nav_left.png +0 -0
- data/spec/coverage/assets/0.3.9/fancybox/fancy_nav_right.png +0 -0
- data/spec/coverage/assets/0.3.9/fancybox/fancy_shadow_e.png +0 -0
- data/spec/coverage/assets/0.3.9/fancybox/fancy_shadow_n.png +0 -0
- data/spec/coverage/assets/0.3.9/fancybox/fancy_shadow_ne.png +0 -0
- data/spec/coverage/assets/0.3.9/fancybox/fancy_shadow_nw.png +0 -0
- data/spec/coverage/assets/0.3.9/fancybox/fancy_shadow_s.png +0 -0
- data/spec/coverage/assets/0.3.9/fancybox/fancy_shadow_se.png +0 -0
- data/spec/coverage/assets/0.3.9/fancybox/fancy_shadow_sw.png +0 -0
- data/spec/coverage/assets/0.3.9/fancybox/fancy_shadow_w.png +0 -0
- data/spec/coverage/assets/0.3.9/fancybox/fancy_title_left.png +0 -0
- data/spec/coverage/assets/0.3.9/fancybox/fancy_title_main.png +0 -0
- data/spec/coverage/assets/0.3.9/fancybox/fancy_title_over.png +0 -0
- data/spec/coverage/assets/0.3.9/fancybox/fancy_title_right.png +0 -0
- data/spec/coverage/assets/0.3.9/fancybox/fancybox-x.png +0 -0
- data/spec/coverage/assets/0.3.9/fancybox/fancybox-y.png +0 -0
- data/spec/coverage/assets/0.3.9/fancybox/fancybox.png +0 -0
- data/spec/coverage/assets/0.3.9/fancybox/jquery.fancybox-1.3.1.css +363 -0
- data/spec/coverage/assets/0.3.9/fancybox/jquery.fancybox-1.3.1.pack.js +44 -0
- data/spec/coverage/assets/0.3.9/favicon.png +0 -0
- data/spec/coverage/assets/0.3.9/jquery-1.4.2.min.js +155 -0
- data/spec/coverage/assets/0.3.9/jquery.dataTables.min.js +152 -0
- data/spec/coverage/assets/0.3.9/jquery.timeago.js +141 -0
- data/spec/coverage/assets/0.3.9/jquery.url.js +174 -0
- data/spec/coverage/assets/0.3.9/loading.gif +0 -0
- data/spec/coverage/assets/0.3.9/magnify.png +0 -0
- data/spec/coverage/assets/0.3.9/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/spec/coverage/assets/0.3.9/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/spec/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/spec/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/spec/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/spec/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/spec/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/spec/coverage/assets/0.3.9/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/spec/coverage/assets/0.3.9/smoothness/images/ui-icons_222222_256x240.png +0 -0
- data/spec/coverage/assets/0.3.9/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
- data/spec/coverage/assets/0.3.9/smoothness/images/ui-icons_454545_256x240.png +0 -0
- data/spec/coverage/assets/0.3.9/smoothness/images/ui-icons_888888_256x240.png +0 -0
- data/spec/coverage/assets/0.3.9/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/spec/coverage/assets/0.3.9/smoothness/jquery-ui-1.8.4.custom.css +295 -0
- data/spec/coverage/assets/0.3.9/stylesheet.css +341 -0
- data/spec/coverage/index.html +43412 -0
- data/spec/coverage/resultset.yml +3251 -0
- data/spec/data/configuration_override.yml +2 -1
- data/spec/digestion_tract/api_response_digestor_spec.rb +15 -1
- data/spec/digestion_tract/artist_digestor_spec.rb +3 -3
- data/spec/digestion_tract/basket_digestor_spec.rb +32 -0
- data/spec/digestion_tract/basket_item_digestor_spec.rb +58 -0
- data/spec/digestion_tract/chart_digestor_spec.rb +2 -2
- data/spec/digestion_tract/download_url_digestor_spec.rb +41 -0
- data/spec/digestion_tract/format_digestor_spec.rb +2 -2
- data/spec/digestion_tract/label_digestor_spec.rb +2 -2
- data/spec/digestion_tract/locker_digestor_spec.rb +31 -0
- data/spec/digestion_tract/locker_release_digestor_spec.rb +71 -0
- data/spec/digestion_tract/locker_track_digestor_spec.rb +56 -0
- data/spec/digestion_tract/oauth_access_token_digestor_spec.rb +35 -0
- data/spec/digestion_tract/oauth_request_token_digestor_spec.rb +35 -0
- data/spec/digestion_tract/pager_digestor_spec.rb +2 -2
- data/spec/digestion_tract/price_digestor_spec.rb +21 -5
- data/spec/digestion_tract/release_digestor_spec.rb +2 -2
- data/spec/digestion_tract/tag_digestor_spec.rb +46 -0
- data/spec/digestion_tract/track_digestor_spec.rb +1 -1
- data/spec/management/artist_manager_spec.rb +46 -41
- data/spec/management/basket_manager_spec.rb +78 -0
- data/spec/management/oauth_manager_spec.rb +73 -0
- data/spec/management/release_manager_spec.rb +33 -74
- data/spec/management/tag_manager_spec.rb +34 -0
- data/spec/management/track_manager_spec.rb +42 -25
- data/spec/management/user_manager_spec.rb +163 -0
- data/spec/model/api_response_spec.rb +69 -2
- data/spec/model/artist_spec.rb +1 -26
- data/spec/model/basket_spec.rb +63 -0
- data/spec/model/coverage/assets/0.3.9/app.js +66 -0
- data/spec/model/coverage/assets/0.3.9/fancybox/blank.gif +0 -0
- data/spec/model/coverage/assets/0.3.9/fancybox/fancy_close.png +0 -0
- data/spec/model/coverage/assets/0.3.9/fancybox/fancy_loading.png +0 -0
- data/spec/model/coverage/assets/0.3.9/fancybox/fancy_nav_left.png +0 -0
- data/spec/model/coverage/assets/0.3.9/fancybox/fancy_nav_right.png +0 -0
- data/spec/model/coverage/assets/0.3.9/fancybox/fancy_shadow_e.png +0 -0
- data/spec/model/coverage/assets/0.3.9/fancybox/fancy_shadow_n.png +0 -0
- data/spec/model/coverage/assets/0.3.9/fancybox/fancy_shadow_ne.png +0 -0
- data/spec/model/coverage/assets/0.3.9/fancybox/fancy_shadow_nw.png +0 -0
- data/spec/model/coverage/assets/0.3.9/fancybox/fancy_shadow_s.png +0 -0
- data/spec/model/coverage/assets/0.3.9/fancybox/fancy_shadow_se.png +0 -0
- data/spec/model/coverage/assets/0.3.9/fancybox/fancy_shadow_sw.png +0 -0
- data/spec/model/coverage/assets/0.3.9/fancybox/fancy_shadow_w.png +0 -0
- data/spec/model/coverage/assets/0.3.9/fancybox/fancy_title_left.png +0 -0
- data/spec/model/coverage/assets/0.3.9/fancybox/fancy_title_main.png +0 -0
- data/spec/model/coverage/assets/0.3.9/fancybox/fancy_title_over.png +0 -0
- data/spec/model/coverage/assets/0.3.9/fancybox/fancy_title_right.png +0 -0
- data/spec/model/coverage/assets/0.3.9/fancybox/fancybox-x.png +0 -0
- data/spec/model/coverage/assets/0.3.9/fancybox/fancybox-y.png +0 -0
- data/spec/model/coverage/assets/0.3.9/fancybox/fancybox.png +0 -0
- data/spec/model/coverage/assets/0.3.9/fancybox/jquery.fancybox-1.3.1.css +363 -0
- data/spec/model/coverage/assets/0.3.9/fancybox/jquery.fancybox-1.3.1.pack.js +44 -0
- data/spec/model/coverage/assets/0.3.9/favicon.png +0 -0
- data/spec/model/coverage/assets/0.3.9/jquery-1.4.2.min.js +155 -0
- data/spec/model/coverage/assets/0.3.9/jquery.dataTables.min.js +152 -0
- data/spec/model/coverage/assets/0.3.9/jquery.timeago.js +141 -0
- data/spec/model/coverage/assets/0.3.9/jquery.url.js +174 -0
- data/spec/model/coverage/assets/0.3.9/loading.gif +0 -0
- data/spec/model/coverage/assets/0.3.9/magnify.png +0 -0
- data/spec/model/coverage/assets/0.3.9/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/spec/model/coverage/assets/0.3.9/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/spec/model/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/spec/model/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/spec/model/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/spec/model/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/spec/model/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/spec/model/coverage/assets/0.3.9/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/spec/model/coverage/assets/0.3.9/smoothness/images/ui-icons_222222_256x240.png +0 -0
- data/spec/model/coverage/assets/0.3.9/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
- data/spec/model/coverage/assets/0.3.9/smoothness/images/ui-icons_454545_256x240.png +0 -0
- data/spec/model/coverage/assets/0.3.9/smoothness/images/ui-icons_888888_256x240.png +0 -0
- data/spec/model/coverage/assets/0.3.9/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/spec/model/coverage/assets/0.3.9/smoothness/jquery-ui-1.8.4.custom.css +295 -0
- data/spec/model/coverage/assets/0.3.9/stylesheet.css +341 -0
- data/spec/model/coverage/index.html +8637 -0
- data/spec/model/coverage/resultset.yml +642 -0
- data/spec/model/release_spec.rb +15 -14
- data/spec/model/sevendigital_object_spec.rb +74 -0
- data/spec/model/track_spec.rb +8 -4
- data/spec/model/user_spec.rb +98 -0
- data/spec/pager_spec.rb +2 -2
- data/spec/proxy_police_spec.rb +1 -1
- data/spec/spec_helper.rb +11 -3
- data/spec/test-xml/methods/artist/browse.xml +22 -0
- data/spec/test-xml/methods/artist/chart.xml +31 -0
- data/spec/test-xml/methods/basket/additem.xml +24 -0
- data/spec/test-xml/methods/basket/create.xml +11 -0
- data/spec/test-xml/methods/basket/index.xml +24 -0
- data/spec/test-xml/methods/basket/removeitem.xml +11 -0
- data/spec/test-xml/methods/oauth/accesstoken.xml +6 -0
- data/spec/test-xml/methods/oauth/requesttoken.xml +6 -0
- data/spec/test-xml/methods/tag/index.xml +17 -0
- data/spec/test-xml/methods/user/locker.xml +50 -0
- data/spec/test-xml/methods/user/purchase/item.xml +49 -0
- data/spec/test-xml/objects/basket.xml +22 -0
- data/spec/test-xml/objects/basket_item.xml +12 -0
- data/spec/test-xml/objects/basket_item_list.xml +26 -0
- data/spec/test-xml/objects/basket_item_list_empty.xml +2 -0
- data/spec/test-xml/objects/download_url.xml +8 -0
- data/spec/test-xml/objects/locker.xml +48 -0
- data/spec/test-xml/objects/locker_release.xml +41 -0
- data/spec/test-xml/objects/locker_release_list.xml +87 -0
- data/spec/test-xml/objects/locker_release_list_empty.xml +5 -0
- data/spec/test-xml/objects/locker_release_one_item_list.xml +43 -0
- data/spec/test-xml/objects/locker_track.xml +25 -0
- data/spec/test-xml/objects/locker_track_list.xml +26 -0
- data/spec/test-xml/objects/locker_track_list_empty.xml +2 -0
- data/spec/test-xml/objects/oauth_access_token.xml +4 -0
- data/spec/test-xml/objects/oauth_request_token.xml +4 -0
- data/spec/test-xml/objects/tag.xml +5 -0
- metadata +395 -13
- data/lib/sevendigital/peachy_patch.rb +0 -19
data/README.rdoc
CHANGED
@@ -1,9 +1,136 @@
|
|
1
|
-
Ruby wrapper for 7digital API
|
1
|
+
=Ruby wrapper for 7digital API
|
2
|
+
|
3
|
+
This is a ruby wrapper for the 7digital API.
|
4
|
+
|
5
|
+
==About 7digital
|
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
|
8
|
+
|
9
|
+
==Installation
|
10
|
+
|
11
|
+
gem install 7digital
|
12
|
+
|
13
|
+
==Quick start example
|
14
|
+
|
2
15
|
|
3
|
-
Example usage:
|
4
16
|
require "sevendigital"
|
17
|
+
api_client = Sevendigital::Client.new(:oauth_consumer_key => "YOUR_KEY_HERE", :country => "GB")
|
18
|
+
an_artist = api_client.artist.search("radiohead").first
|
19
|
+
a_release = an_artist.releases(:page_size=>100).sort_by{|release| release.year}.last
|
20
|
+
puts "the latest #{an_artist.name} release is #{a_release.title} from #{a_release.year}"
|
21
|
+
puts "go and buy it at #{a_release.url} !"
|
22
|
+
|
23
|
+
==Usage details
|
24
|
+
|
25
|
+
===Initializing & configuring an API Client
|
26
|
+
|
27
|
+
To use the wrapper and access the 7digital API you need a configured instance of Sevendigital::Client. Create one using the standard new method:
|
28
|
+
|
29
|
+
client = Sevendigital::Client.new
|
30
|
+
|
31
|
+
This will get you an API client configured with default settings. At very least before making any API calls you will need to update the configuration with your own API key. You can adjust the client's configuration in several ways:
|
32
|
+
|
33
|
+
1. In Rails app you can put _sevendigital.yml_ inside your app's config dir and this will be automatically picked up (for a template please see the examples directory)
|
34
|
+
|
35
|
+
2. You can provide a custom location of configuration file when instantiating a client
|
36
|
+
|
37
|
+
client = Sevendigital::Client.new("dir/subdir/my_7d_configuration.yml")
|
38
|
+
3. You can supply a hash of configuration settings when instantiating a client
|
39
|
+
|
40
|
+
client = Sevendigital::Client.new(:oauth_consumer_key => "YOUR_KEY_HERE", :country => "GB")
|
41
|
+
4. You can update the configuration in block whilst instantiating a client
|
42
|
+
|
43
|
+
client = Sevendigital::Client.new { |config|
|
44
|
+
config.oauth_consumer_key => "YOUR_KEY_HERE"
|
45
|
+
config.verbose => true
|
46
|
+
}
|
47
|
+
|
48
|
+
You can also combine all of the above (if the same setting is specified multiple times the last one will be applied)
|
49
|
+
An extreme example:
|
50
|
+
|
51
|
+
client = Sevendigital::Client.new("7digital_default_settings.yml", :oauth_consumer_key => "MY_OTHER_KEY") { |conf|
|
52
|
+
conf.country = "SE"
|
53
|
+
conf.oauth_consumer_key = "ACTUALLY_USE_THIS_KEY"
|
54
|
+
}
|
55
|
+
|
56
|
+
===Using the client
|
57
|
+
|
58
|
+
List of all available API methods and their return types
|
59
|
+
|
60
|
+
----
|
61
|
+
|
62
|
+
Provided by Sevendigital::ArtistManager :
|
63
|
+
|
64
|
+
client.artist.*get_details*(artist_id, options={}) => Sevendigital::Artist
|
65
|
+
|
66
|
+
client.artist.*get_releases*(artist_id, options={}) => [ Sevendigital::Release ]
|
67
|
+
|
68
|
+
client.artist.*get_similar*(artist_id, options={}) => [ Sevendigital::Artist ]
|
69
|
+
|
70
|
+
client.artist.*get_top_by_tag*(tags, options={}) => [ Sevendigital::Artist ]
|
71
|
+
|
72
|
+
client.artist.*get_top_tracks*(artist_id, options={}) => [ Sevendigital::Track ]
|
73
|
+
|
74
|
+
client.artist.*search*(query, options={}) => [ Sevendigital::Artist ]
|
75
|
+
|
76
|
+
----
|
77
|
+
|
78
|
+
Provided by Sevendigital::ReleaseManager :
|
79
|
+
|
80
|
+
client.release.*get_details*(release_id, options = {}) => Sevendigital::Release
|
81
|
+
|
82
|
+
client.release.*get_tracks*(release_id, options = {}) => [ Sevendigital::Track ]
|
83
|
+
|
84
|
+
client.release.*get_chart*(options={}) => [ Sevendigital::ChartItem ]
|
85
|
+
|
86
|
+
client.release.*get_by_date*(from_date = nil, to_date = nil, options = {}) => [ Sevendigital::Release ]
|
87
|
+
|
88
|
+
client.release.*get_recommendations*(release_id, options = {}) => [ Sevendigital::Release ]
|
89
|
+
|
90
|
+
client.release.*get_top_by_tag*(tags, options = {}) => [ Sevendigital::Release ]
|
91
|
+
|
92
|
+
client.release.*search*(query, options={}) => [ Sevendigital::Release ]
|
93
|
+
|
94
|
+
----
|
95
|
+
|
96
|
+
client.track.*get_details*(id, options={}) => Sevendigital::Track
|
97
|
+
|
98
|
+
client.track.*get_details_from_release*(track_id, release_id, options={}) => Sevendigital::Track
|
99
|
+
|
100
|
+
client.track.*get_chart*(options={}) => [ Sevendigital::ChartItem ]
|
101
|
+
|
102
|
+
client.track.*build_preview_url*(id, options={}) => String
|
103
|
+
|
104
|
+
client.track.*search*(query, options={}) => [ Sevendigital::Track ]
|
105
|
+
|
106
|
+
---
|
107
|
+
|
108
|
+
client.basket.*get*(basket_id, options={}) => Sevendigital::Basket
|
109
|
+
|
110
|
+
client.basket.*create*(options={}) => Sevendigital::Basket
|
111
|
+
|
112
|
+
client.basket.*add_item*(basket_id, release_id, track_id=nil, options={}) => Sevendigital::Basket
|
113
|
+
|
114
|
+
client.basket.*remove_item*(basket_id, item_id, options={}) => Sevendigital::Basket
|
115
|
+
|
116
|
+
---
|
117
|
+
|
118
|
+
client.oauth.*get_request_token* => OAuth::RequestToken
|
119
|
+
|
120
|
+
client.oauth.*get_access_token*(request_token) => OAuth::AccessToken
|
121
|
+
|
122
|
+
---
|
123
|
+
|
124
|
+
client.user.*login*(access_token) => Sevendigital::User
|
125
|
+
|
126
|
+
client.user.*authenticate*(email, password) => Sevendigital::User
|
127
|
+
|
128
|
+
client.user.*get_locker*(token, options={}) => Sevendgital::Locker
|
129
|
+
|
130
|
+
client.user.*purchase*(release_id, track_id, price, token, options={}) => Sevendgital::Locker
|
131
|
+
|
132
|
+
client.user.*get_stream_track_url*(release_id, track_id, token, options={}) => String
|
133
|
+
|
134
|
+
client.user.*get_add_card_url*(return_url, token, options={}) => String
|
5
135
|
|
6
|
-
sevendigital_client = Sevendigital::Client.new(:oauth_consumer_key => "YOUR_KEY_HERE", :country => "GB")
|
7
|
-
artist = sevendigital_client.artist.get_details(1)
|
8
|
-
puts artist.name
|
9
136
|
|
data/lib/sevendigital.rb
CHANGED
@@ -2,7 +2,6 @@
|
|
2
2
|
module Sevendigital
|
3
3
|
|
4
4
|
# :stopdoc:
|
5
|
-
VERSION = '0.0.1'
|
6
5
|
LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
|
7
6
|
PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
|
8
7
|
# :startdoc:
|
@@ -45,8 +44,8 @@ module Sevendigital
|
|
45
44
|
end # module 7digital
|
46
45
|
|
47
46
|
require 'peachy'
|
48
|
-
require File.join( File.dirname( File.expand_path(__FILE__)), 'sevendigital', 'peachy_patch')
|
49
47
|
Peachy.be_quiet
|
48
|
+
require File.join( File.dirname( File.expand_path(__FILE__)), 'sevendigital', 'client_configuration')
|
50
49
|
require File.join( File.dirname( File.expand_path(__FILE__)), 'sevendigital', 'management', 'manager')
|
51
50
|
require File.join( File.dirname( File.expand_path(__FILE__)), 'sevendigital', 'digestion_tract', 'digestor')
|
52
51
|
require File.join( File.dirname( File.expand_path(__FILE__)), 'sevendigital', 'model', 'sevendigital_object')
|
@@ -1,32 +1,123 @@
|
|
1
1
|
module Sevendigital
|
2
2
|
|
3
3
|
require 'net/http'
|
4
|
-
|
5
|
-
|
4
|
+
require 'net/https'
|
5
|
+
require 'oauth'
|
6
|
+
require 'uri'
|
7
|
+
require 'cgi'
|
8
|
+
|
9
|
+
#internal class used for translating ApiRequests into http calls
|
10
|
+
#deals with OAuth signing requests that require signature, making sure parameters are in correct format etc
|
11
|
+
class ApiOperator # :nodoc:
|
12
|
+
|
13
|
+
RESERVED_CHARACTERS = /[^a-zA-Z0-9\-\.\_\~]/
|
6
14
|
|
7
15
|
def initialize(client)
|
8
16
|
@client = client
|
9
17
|
end
|
10
18
|
|
11
19
|
def call_api(api_request)
|
12
|
-
api_response = make_http_request_and_digest(
|
13
|
-
puts api_response if @client.very_verbose?
|
20
|
+
api_response = make_http_request_and_digest(api_request)
|
21
|
+
puts api_response.content.to_s if @client.very_verbose?
|
14
22
|
api_response
|
15
23
|
end
|
16
24
|
|
17
|
-
def
|
18
|
-
|
19
|
-
|
25
|
+
def get_request_uri(api_request)
|
26
|
+
api_request.signature_scheme = :query_string if api_request.requires_signature?
|
27
|
+
http_client, http_request = create_http_request(api_request)
|
28
|
+
path = http_request.instance_variable_get("@path")
|
29
|
+
host = http_client.instance_variable_get("@address")
|
30
|
+
port = http_client.instance_variable_get("@port")
|
31
|
+
scheme = port == 443 ? "https" : "http"
|
32
|
+
return "#{scheme}://#{host}#{path}"
|
33
|
+
end
|
34
|
+
|
35
|
+
def make_http_request_and_digest(api_request)
|
36
|
+
digest_http_response(make_http_request(api_request))
|
37
|
+
end
|
38
|
+
|
39
|
+
def make_http_request(api_request)
|
40
|
+
|
41
|
+
http_client, http_request = create_http_request(api_request)
|
42
|
+
|
43
|
+
http_client.set_debug_output($stdout) if @client.very_verbose?
|
44
|
+
log_request(http_request) if @client.verbose?
|
45
|
+
|
46
|
+
http_client.request(http_request)
|
47
|
+
end
|
48
|
+
|
49
|
+
def digest_http_response(http_response)
|
20
50
|
api_response = @client.api_response_digestor.from_http_response(http_response)
|
21
|
-
raise Sevendigital::SevendigitalError, "#{api_response.error_code} - #{api_response.error_message}" if !api_response.ok?
|
51
|
+
raise Sevendigital::SevendigitalError.new(api_response.error_code, api_response.error_message), "#{api_response.error_code} - #{api_response.error_message}" if !api_response.ok?
|
22
52
|
api_response
|
23
53
|
end
|
24
54
|
|
55
|
+
def create_http_request(api_request)
|
56
|
+
http_client, http_request = create_standard_http_request(api_request)
|
57
|
+
if (api_request.requires_signature?) then
|
58
|
+
oauth_sign_request(http_client, http_request, api_request)
|
59
|
+
else
|
60
|
+
end
|
61
|
+
return http_client, http_request
|
62
|
+
end
|
63
|
+
|
64
|
+
def oauth_sign_request(http_client, http_request, api_request)
|
65
|
+
http_request.oauth!( \
|
66
|
+
http_client, \
|
67
|
+
@client.oauth_consumer, \
|
68
|
+
api_request.token, \
|
69
|
+
{:scheme => api_request.signature_scheme}
|
70
|
+
)
|
71
|
+
return http_request
|
72
|
+
end
|
73
|
+
|
74
|
+
def create_standard_http_request(api_request)
|
75
|
+
request_uri = create_request_uri(api_request)
|
76
|
+
http_client = Net::HTTP.new(request_uri.host, request_uri.port)
|
77
|
+
|
78
|
+
request_uri.query += '&oauth_consumer_key=' + @client.configuration.oauth_consumer_key unless api_request.requires_signature?
|
79
|
+
|
80
|
+
http_request = new_http_request(request_uri.request_uri, api_request.http_method)
|
81
|
+
|
82
|
+
ensure_secure_connection(http_client) if api_request.requires_secure_connection?
|
83
|
+
add_form_parameters(http_request, api_request)
|
84
|
+
|
85
|
+
return http_client, http_request
|
86
|
+
end
|
87
|
+
|
88
|
+
def ensure_secure_connection(http_client)
|
89
|
+
http_client.use_ssl = true
|
90
|
+
http_client.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
91
|
+
end
|
92
|
+
|
25
93
|
def create_request_uri(api_request)
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
94
|
+
host, version = @client.api_host_and_version(api_request.api_service)
|
95
|
+
path = "/#{version}/#{api_request.api_method}"
|
96
|
+
query = api_request.parameters.map{ |k,v| "#{escape(k)}=#{escape(v)}" }.join("&")
|
97
|
+
if api_request.requires_secure_connection? then
|
98
|
+
URI::HTTPS.build(:host => host, :path => path, :query =>query)
|
99
|
+
else
|
100
|
+
URI::HTTP.build(:host => host, :path => path, :query =>query)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def escape(value)
|
105
|
+
URI::escape(value.to_s, RESERVED_CHARACTERS)
|
106
|
+
rescue ArgumentError
|
107
|
+
URI::escape(value.to_s.force_encoding(Encoding::UTF_8), RESERVED_CHARACTERS)
|
108
|
+
end
|
109
|
+
|
110
|
+
def new_http_request(request_uri, http_method)
|
111
|
+
request_type = Kernel.const_get("Net").const_get("HTTP").const_get(http_method.to_s.capitalize)
|
112
|
+
request_type.new(request_uri, {"user-agent" => @client.user_agent_info})
|
113
|
+
end
|
114
|
+
|
115
|
+
def add_form_parameters(http_request, api_request)
|
116
|
+
http_request.set_form_data(api_request.form_parameters)
|
117
|
+
end
|
118
|
+
|
119
|
+
def log_request(request)
|
120
|
+
puts "ApiOperator: Calling #{request.inspect}"
|
30
121
|
end
|
31
122
|
|
32
123
|
end
|
@@ -1,6 +1,10 @@
|
|
1
1
|
module Sevendigital
|
2
2
|
|
3
|
-
|
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:
|
4
8
|
|
5
9
|
def initialize(client, cache)
|
6
10
|
@cache = cache
|
@@ -8,16 +12,18 @@ class ApiOperatorCached < ApiOperator
|
|
8
12
|
end
|
9
13
|
|
10
14
|
def call_api(api_request)
|
11
|
-
|
12
|
-
api_response = @cache.get(
|
13
|
-
puts "ApiOperatorCached: Got from cache #{
|
14
|
-
if
|
15
|
-
|
16
|
-
|
15
|
+
request_cache_key = create_request_uri(api_request)
|
16
|
+
api_response = @cache.get(request_cache_key.to_s) if !api_request.requires_signature?
|
17
|
+
puts "ApiOperatorCached: Got from cache #{request_cache_key}" if @client.verbose? && api_response
|
18
|
+
puts "but the response is out of date" if @client.verbose? && api_response && api_response.out_of_date?
|
19
|
+
if (!api_response || api_response.out_of_date?) then
|
20
|
+
api_response = make_http_request_and_digest(api_request)
|
21
|
+
@cache.set(request_cache_key.to_s, api_response) if !api_request.requires_signature?
|
17
22
|
end
|
18
|
-
|
23
|
+
p api_response if @client.very_verbose?
|
19
24
|
api_response
|
20
25
|
end
|
26
|
+
|
21
27
|
end
|
22
28
|
|
23
29
|
end
|
@@ -1,24 +1,65 @@
|
|
1
1
|
module Sevendigital
|
2
2
|
|
3
|
-
|
3
|
+
#Abstraction of a HTTP API request, ApiOperator uses this ApiRequest to build a real HTTP requests
|
4
|
+
class ApiRequest # :nodoc:
|
4
5
|
|
5
|
-
attr_reader :api_method, :parameters
|
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
|
6
10
|
|
7
|
-
def initialize(api_method, parameters, options
|
11
|
+
def initialize(api_method, parameters, options={})
|
8
12
|
@api_method = api_method
|
9
|
-
@parameters =
|
13
|
+
@parameters = parameters
|
14
|
+
@signature_scheme = :header
|
15
|
+
@http_method = :GET
|
16
|
+
comb_parameters(parameters)
|
17
|
+
@form_parameters = Hash.new
|
18
|
+
end
|
19
|
+
|
20
|
+
def form_parameters
|
21
|
+
comb_parameters(@form_parameters)
|
22
|
+
end
|
23
|
+
|
24
|
+
def requires_signature?
|
25
|
+
@signed == true
|
26
|
+
end
|
27
|
+
|
28
|
+
def require_signature
|
29
|
+
@signed = true
|
30
|
+
end
|
31
|
+
|
32
|
+
def requires_secure_connection?
|
33
|
+
@secure == true
|
34
|
+
end
|
35
|
+
|
36
|
+
def require_secure_connection
|
37
|
+
@secure = true
|
10
38
|
end
|
11
39
|
|
12
40
|
def comb_parameters(parameters)
|
13
|
-
|
14
|
-
parameters
|
15
|
-
|
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
|
16
46
|
end
|
17
47
|
|
18
|
-
def
|
19
|
-
|
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
|
20
56
|
end
|
21
57
|
|
58
|
+
def remove_empty_parameters(parameters)
|
59
|
+
parameters.delete_if { |key, value| value.nil? }
|
60
|
+
end
|
61
|
+
|
62
|
+
|
22
63
|
end
|
23
64
|
|
24
65
|
end
|
data/lib/sevendigital/client.rb
CHANGED
@@ -1,108 +1,82 @@
|
|
1
|
-
require 'ostruct'
|
2
|
-
require 'yaml'
|
3
|
-
|
4
|
-
|
5
1
|
module Sevendigital
|
6
2
|
|
7
|
-
DEFAULT_CONFIGURATION = {
|
8
|
-
:api_url => "api.7digital.com",
|
9
|
-
:api_version => "1.2"
|
10
|
-
}
|
11
|
-
|
12
3
|
class Client
|
13
4
|
|
14
|
-
|
15
|
-
plain_settings = YAML.load_file(file_name)
|
16
|
-
if (plain_settings["common"] || (environment && plain_settings[environment])) then
|
17
|
-
environment_settings = plain_settings["common"] || {}
|
18
|
-
environment_settings.update(plain_settings[environment]) if environment
|
19
|
-
environment_settings
|
20
|
-
else
|
21
|
-
plain_settings
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
def load_configurations(configuration)
|
26
|
-
|
27
|
-
default_settings = Sevendigital::DEFAULT_CONFIGURATION
|
5
|
+
COMMON_REQUEST_PARAMETERS = [:shop_id, :country, :page, :page_size, :image_size]
|
28
6
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
explicit_settings = configuration if configuration.kind_of? Hash
|
34
|
-
explicit_settings = configuration.marshal_dump if configuration.kind_of? OpenStruct
|
7
|
+
def initialize(*args)
|
8
|
+
@configuration = Sevendigital::ClientConfiguration.new(*args)
|
9
|
+
yield @configuration if block_given?
|
10
|
+
@api_operator = hire_api_operator
|
35
11
|
end
|
36
12
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
return OpenStruct.new(settings)
|
45
|
-
end
|
46
|
-
|
47
|
-
#Code here
|
48
|
-
|
49
|
-
def initialize(configuration=nil, api_operator=nil)
|
50
|
-
@configuration = load_configurations(configuration)
|
51
|
-
@api_operator = api_operator || hire_api_operator
|
13
|
+
def default_parameters
|
14
|
+
params = {}
|
15
|
+
COMMON_REQUEST_PARAMETERS.each do |param|
|
16
|
+
value = @configuration.send(param)
|
17
|
+
params[param] = value if value
|
18
|
+
end
|
19
|
+
params
|
52
20
|
end
|
53
21
|
|
54
22
|
def hire_api_operator
|
55
23
|
@configuration.cache ? ApiOperatorCached.new(self, @configuration.cache) : ApiOperator.new(self)
|
56
24
|
end
|
57
25
|
|
58
|
-
def
|
59
|
-
@
|
26
|
+
def user_agent_info
|
27
|
+
app_info = @configuration.app_name ? "/#{@configuration.app_name}" : nil
|
28
|
+
app_info += " #{@configuration.app_version}" if app_info && @configuration.app_version
|
29
|
+
"#{Sevendigital::NAME} Gem #{Sevendigital::VERSION}#{app_info}"
|
60
30
|
end
|
61
31
|
|
62
|
-
def
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
def release
|
67
|
-
@release_manager ||= ReleaseManager.new(self)
|
32
|
+
def create_api_request(api_method, parameters, options = {})
|
33
|
+
parameters = options.merge(parameters)
|
34
|
+
parameters = add_default_parameters(parameters)
|
35
|
+
ApiRequest.new(api_method, parameters)
|
68
36
|
end
|
69
37
|
|
70
|
-
def
|
71
|
-
|
38
|
+
def make_api_request(api_method, parameters, options = {})
|
39
|
+
api_request = create_api_request(api_method, parameters, options)
|
40
|
+
operator.call_api(api_request)
|
72
41
|
end
|
73
42
|
|
74
|
-
def
|
75
|
-
|
76
|
-
|
43
|
+
def make_signed_api_request(api_method, parameters, options = {}, token = nil)
|
44
|
+
api_request = create_api_request(api_method, parameters, options)
|
45
|
+
api_request.require_signature
|
46
|
+
api_request.require_secure_connection
|
47
|
+
api_request.token = token
|
77
48
|
|
78
|
-
|
79
|
-
@format_digestor ||= FormatDigestor.new(self)
|
80
|
-
end
|
81
|
-
|
82
|
-
def price_digestor
|
83
|
-
@price_digestor ||= PriceDigestor.new(self)
|
49
|
+
operator.call_api(api_request)
|
84
50
|
end
|
85
51
|
|
86
|
-
def
|
87
|
-
|
52
|
+
def add_default_parameters(parameters)
|
53
|
+
params = parameters
|
54
|
+
default_parameters.each do |name, value|
|
55
|
+
params[name] ||= value
|
56
|
+
end
|
57
|
+
params
|
88
58
|
end
|
89
59
|
|
90
|
-
def
|
91
|
-
|
60
|
+
def api_host_and_version(api_service=nil)
|
61
|
+
service = api_service && !api_service.to_s.empty? ? "#{api_service}_" : ""
|
62
|
+
return configuration.send("#{service}api_url".to_sym), configuration.send("#{service}api_version".to_sym)
|
92
63
|
end
|
93
64
|
|
94
|
-
def
|
95
|
-
|
96
|
-
end
|
65
|
+
def oauth_consumer
|
66
|
+
host, version = api_host_and_version(:account)
|
97
67
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
@
|
68
|
+
consumer_options = {
|
69
|
+
:authorize_path => "https://#{host}/#{version}/oauth/authorise",
|
70
|
+
:http_method => :get
|
71
|
+
}
|
72
|
+
|
73
|
+
@oauth_consumer ||= OAuth::Consumer.new( \
|
74
|
+
@configuration.oauth_consumer_key, \
|
75
|
+
@configuration.oauth_consumer_secret, \
|
76
|
+
consumer_options \
|
77
|
+
)
|
104
78
|
end
|
105
|
-
|
79
|
+
|
106
80
|
def configuration
|
107
81
|
return @configuration
|
108
82
|
end
|
@@ -111,14 +85,6 @@ module Sevendigital
|
|
111
85
|
@api_operator
|
112
86
|
end
|
113
87
|
|
114
|
-
def country
|
115
|
-
@country || @configuration.country
|
116
|
-
end
|
117
|
-
|
118
|
-
def country=(country_code)
|
119
|
-
@country = country_code
|
120
|
-
end
|
121
|
-
|
122
88
|
def verbose?
|
123
89
|
!(@verbose || @configuration.verbose).nil?
|
124
90
|
end
|
@@ -127,10 +93,6 @@ module Sevendigital
|
|
127
93
|
verbose? && (@verbose || @configuration.verbose).to_s == "very_verbose"
|
128
94
|
end
|
129
95
|
|
130
|
-
def verbose=(verbosity)
|
131
|
-
@verbose = verbosity
|
132
|
-
end
|
133
|
-
|
134
96
|
end
|
135
97
|
|
136
98
|
end
|