myspaceid-sdk 0.1.8

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 (115) hide show
  1. data/README +30 -0
  2. data/lib/myspace.rb +15 -0
  3. data/lib/myspace/exceptions.rb +31 -0
  4. data/lib/myspace/myspace.rb +565 -0
  5. data/lib/myspace/oauth.rb +62 -0
  6. data/lib/patches.rb +42 -0
  7. data/samples/rails/README +83 -0
  8. data/samples/rails/consumer_key.rb +4 -0
  9. data/samples/rails/consumer_key.rb-copyme +4 -0
  10. data/samples/rails/sample/README +256 -0
  11. data/samples/rails/sample/Rakefile +10 -0
  12. data/samples/rails/sample/app/controllers/application.rb +15 -0
  13. data/samples/rails/sample/app/controllers/oauth_controller.rb +68 -0
  14. data/samples/rails/sample/app/controllers/openid_controller.rb +105 -0
  15. data/samples/rails/sample/app/controllers/user_controller.rb +96 -0
  16. data/samples/rails/sample/app/helpers/application_helper.rb +3 -0
  17. data/samples/rails/sample/app/helpers/oauth_helper.rb +2 -0
  18. data/samples/rails/sample/app/helpers/openid_helper.rb +2 -0
  19. data/samples/rails/sample/app/helpers/user_helper.rb +90 -0
  20. data/samples/rails/sample/app/views/oauth/error.rhtml +8 -0
  21. data/samples/rails/sample/app/views/oauth/index.rhtml +8 -0
  22. data/samples/rails/sample/app/views/oauth/profile.rhtml +74 -0
  23. data/samples/rails/sample/app/views/openid/index.rhtml +125 -0
  24. data/samples/rails/sample/app/views/user/complete.rhtml +59 -0
  25. data/samples/rails/sample/app/views/user/index.rhtml +157 -0
  26. data/samples/rails/sample/config/boot.rb +109 -0
  27. data/samples/rails/sample/config/database.yml +22 -0
  28. data/samples/rails/sample/config/environment.rb +75 -0
  29. data/samples/rails/sample/config/environments/development.rb +17 -0
  30. data/samples/rails/sample/config/environments/production.rb +24 -0
  31. data/samples/rails/sample/config/environments/test.rb +22 -0
  32. data/samples/rails/sample/config/initializers/inflections.rb +10 -0
  33. data/samples/rails/sample/config/initializers/mime_types.rb +5 -0
  34. data/samples/rails/sample/config/initializers/new_rails_defaults.rb +17 -0
  35. data/samples/rails/sample/config/locales/en.yml +5 -0
  36. data/samples/rails/sample/config/routes.rb +43 -0
  37. data/samples/rails/sample/db/development.sqlite3 +0 -0
  38. data/samples/rails/sample/doc/README_FOR_APP +5 -0
  39. data/samples/rails/sample/public/404.html +30 -0
  40. data/samples/rails/sample/public/422.html +30 -0
  41. data/samples/rails/sample/public/500.html +33 -0
  42. data/samples/rails/sample/public/dispatch.cgi +10 -0
  43. data/samples/rails/sample/public/dispatch.fcgi +24 -0
  44. data/samples/rails/sample/public/dispatch.rb +10 -0
  45. data/samples/rails/sample/public/favicon.ico +0 -0
  46. data/samples/rails/sample/public/images/8b_Home.jpg +0 -0
  47. data/samples/rails/sample/public/images/8b_homecomp_200.jpg +0 -0
  48. data/samples/rails/sample/public/images/8b_profile_page_201.jpg +0 -0
  49. data/samples/rails/sample/public/images/LArge_150x35_myspaceID.png +0 -0
  50. data/samples/rails/sample/public/images/MySpaceID-loginwith-156x28.png +0 -0
  51. data/samples/rails/sample/public/images/appengine_button_noborder.gif +0 -0
  52. data/samples/rails/sample/public/images/background.png +0 -0
  53. data/samples/rails/sample/public/images/blue_150_Loginwithmyspaceid.png +0 -0
  54. data/samples/rails/sample/public/images/blue_150_signupwithmyspaceid.png +0 -0
  55. data/samples/rails/sample/public/images/blue_90_myspaceid.png +0 -0
  56. data/samples/rails/sample/public/images/button-background.gif +0 -0
  57. data/samples/rails/sample/public/images/grey_150_Loginwithmyspaceid.png +0 -0
  58. data/samples/rails/sample/public/images/grey_180_signupwithmyspaceid.png +0 -0
  59. data/samples/rails/sample/public/images/grey_90_myspaceid.png +0 -0
  60. data/samples/rails/sample/public/images/image.gif +0 -0
  61. data/samples/rails/sample/public/images/keyhole_buttons_only.png +0 -0
  62. data/samples/rails/sample/public/images/level_icon.png +0 -0
  63. data/samples/rails/sample/public/images/myspaceid.png +0 -0
  64. data/samples/rails/sample/public/images/nav_select.png +0 -0
  65. data/samples/rails/sample/public/images/openid-16x16.gif +0 -0
  66. data/samples/rails/sample/public/images/openid-icon.png +0 -0
  67. data/samples/rails/sample/public/images/openid-logo.png +0 -0
  68. data/samples/rails/sample/public/images/profile_icon.png +0 -0
  69. data/samples/rails/sample/public/images/profile_pic.png +0 -0
  70. data/samples/rails/sample/public/images/rails.png +0 -0
  71. data/samples/rails/sample/public/images/ranking_badge.png +0 -0
  72. data/samples/rails/sample/public/images/song_play.png +0 -0
  73. data/samples/rails/sample/public/images/song_sound.png +0 -0
  74. data/samples/rails/sample/public/images/star_grey.png +0 -0
  75. data/samples/rails/sample/public/images/star_yellow.png +0 -0
  76. data/samples/rails/sample/public/index.html +19 -0
  77. data/samples/rails/sample/public/index.html.orig +274 -0
  78. data/samples/rails/sample/public/javascripts/application.js +2 -0
  79. data/samples/rails/sample/public/javascripts/controls.js +963 -0
  80. data/samples/rails/sample/public/javascripts/dragdrop.js +973 -0
  81. data/samples/rails/sample/public/javascripts/effects.js +1128 -0
  82. data/samples/rails/sample/public/javascripts/myspaceid.rev.0.js +103 -0
  83. data/samples/rails/sample/public/javascripts/prototype.js +4320 -0
  84. data/samples/rails/sample/public/robots.txt +5 -0
  85. data/samples/rails/sample/public/stylesheets/base.css +46 -0
  86. data/samples/rails/sample/public/stylesheets/main.css +65 -0
  87. data/samples/rails/sample/public/stylesheets/openid.css +119 -0
  88. data/samples/rails/sample/script/about +4 -0
  89. data/samples/rails/sample/script/console +3 -0
  90. data/samples/rails/sample/script/dbconsole +3 -0
  91. data/samples/rails/sample/script/destroy +3 -0
  92. data/samples/rails/sample/script/generate +3 -0
  93. data/samples/rails/sample/script/performance/benchmarker +3 -0
  94. data/samples/rails/sample/script/performance/profiler +3 -0
  95. data/samples/rails/sample/script/performance/request +3 -0
  96. data/samples/rails/sample/script/plugin +3 -0
  97. data/samples/rails/sample/script/process/inspector +3 -0
  98. data/samples/rails/sample/script/process/reaper +3 -0
  99. data/samples/rails/sample/script/process/spawner +3 -0
  100. data/samples/rails/sample/script/runner +3 -0
  101. data/samples/rails/sample/script/server +3 -0
  102. data/samples/rails/sample/test/functional/oauth_controller_test.rb +8 -0
  103. data/samples/rails/sample/test/functional/openid_controller_test.rb +8 -0
  104. data/samples/rails/sample/test/functional/user_controller_test.rb +8 -0
  105. data/samples/rails/sample/test/performance/browsing_test.rb +9 -0
  106. data/samples/rails/sample/test/test_helper.rb +38 -0
  107. data/test/data.rb +8 -0
  108. data/test/myspace_test.rb +13 -0
  109. data/test/tc_albums.rb +126 -0
  110. data/test/tc_friends.rb +96 -0
  111. data/test/tc_profile.rb +107 -0
  112. data/test/tc_videos.rb +125 -0
  113. data/test/test_data.rb +14 -0
  114. data/test/ts_alltests.rb +7 -0
  115. metadata +222 -0
data/README ADDED
@@ -0,0 +1,30 @@
1
+ MySpaceID lets your users log on using their MySpace account info,
2
+ after which their MySpaceID data becomes available; that is, your web
3
+ servers will be able to communicate with our web servers and request
4
+ user data.
5
+
6
+ This SDK project contains examples of the base API code necessary to
7
+ make signed requests against the MySpaceID REST API.
8
+
9
+ To use the MySpaceID API, you first need to register on the MySpace
10
+ Developer Site, create an app, and obtain a consumer key and
11
+ secret. Information about these procedures, and about MySpaceID in
12
+ general, is available at the MySpaceID Developer Wiki:
13
+
14
+ http://wiki.developer.myspace.com/index.php?title=Category:MySpaceID
15
+
16
+ The MySpaceID Ruby SDK enables you to work with MySpace data using the
17
+ OpenStack (OpenID, OAuth etc) and the MySpace REST APIs via
18
+ easy-to-use high level interfaces.
19
+
20
+ The best way to implement your own application is to take an existing
21
+ sample and customize it. Working Examples in this SDK:
22
+
23
+ * OAuth - make signed requests
24
+ * OpenID + OAuth Hybrid - delegated login, and making signed requests
25
+
26
+ Documentation
27
+
28
+ * Ruby SDK Documentation Summary: samples/rails/README
29
+ * Ruby SDK - API Documentation: http://myspaceid-ruby-sdk.googlecode.com/svn/trunk/doc/index.html
30
+
@@ -0,0 +1,15 @@
1
+ require 'rubygems'
2
+ require 'oauth/consumer'
3
+ require 'openid/consumer'
4
+ require 'json'
5
+ require 'logger'
6
+
7
+ require 'patches'
8
+
9
+ module MySpace
10
+ end
11
+
12
+ require 'myspace/myspace'
13
+ require 'myspace/exceptions'
14
+ require 'myspace/oauth'
15
+
@@ -0,0 +1,31 @@
1
+ module MySpace
2
+ class MySpaceException < Exception
3
+ end
4
+
5
+ class BadIdentifier < MySpaceException
6
+ attr_reader :parameter, :identifier
7
+ def initialize(parameter, identifier)
8
+ @parameter = parameter
9
+ @identifier = identifier
10
+ end
11
+ end
12
+
13
+ class RestException < MySpaceException
14
+ attr_reader :code, :message, :url
15
+ def initialize(code, message, url)
16
+ @code = code
17
+ @message = message
18
+ @url = url
19
+ end
20
+
21
+ def to_s
22
+ "#<MySpace::RestException: #{@code}: '#{@message}' loading '#{@url}'>"
23
+ end
24
+ end
25
+
26
+ class PermissionDenied < RestException
27
+ def to_s
28
+ "#<PermissionDenied loading '#{url}'>"
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,565 @@
1
+ module MySpace
2
+ # The MySpace API object provides access to the MySpace REST API.
3
+ class MySpace
4
+ APPLICATION_TYPE_ONSITE = 'onsite' unless const_defined?('APPLICATION_TYPE_ONSITE')
5
+ APPLICATION_TYPE_OFFSITE = 'offsite' unless const_defined?('APPLICATION_TYPE_OFFSITE')
6
+
7
+ OAUTH_SITES = {
8
+ :prod => 'http://api.myspace.com',
9
+ :stage => 'http://stage-api.myspace.com'
10
+ } unless const_defined?('OAUTH_SITE')
11
+
12
+ OAUTH_REQUEST_TOKEN_URL = '/request_token' unless const_defined?('OAUTH_REQUEST_TOKEN_URL')
13
+ OAUTH_AUTHORIZATION_URL = '/authorize' unless const_defined?('OAUTH_AUTHORIZATION_URL')
14
+ OAUTH_ACCESS_TOKEN_URL = '/access_token' unless const_defined?('OAUTH_ACCESS_TOKEN_URL')
15
+
16
+ API_USERINFO_URL = '/v1/user.json' unless const_defined?('API_USERINFO_URL')
17
+ API_ALBUMS_URL = '/v1/users/%s/albums.json' unless const_defined?('API_ALBUMS_URL')
18
+ API_ALBUM_URL = '/v1/users/%s/albums/%s/photos.json' unless const_defined?('API_ALBUM_URL')
19
+ API_FRIENDS_URL = '/v1/users/%s/friends.json' unless const_defined?('API_FRIENDS_URL')
20
+ API_FRIENDSHIP_URL = '/v1/users/%s/friends/%s.json' unless const_defined?('API_FRIENDSHIP_URL')
21
+ API_MOOD_URL = '/v1/users/%s/mood.json' unless const_defined?('API_MOOD_URL')
22
+ API_PHOTOS_URL = '/v1/users/%s/photos.json' unless const_defined?('API_PHOTOS_URL')
23
+ API_PHOTO_URL = '/v1/users/%s/photos/%s.json' unless const_defined?('API_PHOTO_URL')
24
+ API_PROFILE_URL = '/v1/users/%s/profile.json' unless const_defined?('API_PROFILE_URL')
25
+ API_STATUS_URL = '/v1/users/%s/status.json' unless const_defined?('API_STATUS_URL')
26
+ API_STATUS_PUT_URL = '/v1/users/%s/status' unless const_defined?('API_STATUS_PUT_URL')
27
+ API_VIDEOS_URL = '/v1/users/%s/videos.json' unless const_defined?('API_VIDEOS_URL')
28
+ API_VIDEO_URL = '/v1/users/%s/videos/%s.json' unless const_defined?('API_VIDEO_URL')
29
+ API_ACTIVITIES_URL = '/v1/users/%s/activities.atom' unless const_defined?('API_ACTIVITIES_URL')
30
+ API_FRIENDS_ACTIVITIES_URL = '/v1/users/%s/friends/activities.atom' unless const_defined?('API_FRIENDS_ACTIVITIES_URL')
31
+
32
+ attr_reader :consumer
33
+ attr_accessor :http_logger
34
+ attr_accessor :request_token
35
+ attr_accessor :access_token
36
+
37
+ # Save the application key/secret(s) and initialize OAuth code.
38
+ #
39
+ # If optional param +:application_type+ is passed, it must be one
40
+ # of +MySpace::APPLICATION_TYPE_ONSITE+ or
41
+ # +MySpace::APPLICATION_TYPE_OFFSITE+. If the application is an
42
+ # onsite application, an access token is not required, since the
43
+ # user must separately give your application permission to access
44
+ # their data. If the application is an offsite application, it
45
+ # must get an access token from the user to access their data.
46
+ #
47
+ # If optional param +:request_token+ is passed
48
+ # +:request_token_secret+ must also be passed, and they will be
49
+ # used to create the default argument to
50
+ # +MySpace#get_access_token+ below. If optional param
51
+ # +:access_token+ is passed, +:access_token_secret+ must also be
52
+ # passed, and they will be used to create the access token for the
53
+ # REST API calls.
54
+ #
55
+ # If optional param +:site+ is passed, it must be either +:prod+
56
+ # or +:stage+, and MySpace OAuth calls will be directed to either
57
+ # the production or stage API server accordingly.
58
+ def initialize(oauth_token_key, oauth_token_secret, params = {})
59
+ @http_logger = params[:logger]
60
+ site = params[:site] || :prod
61
+ @consumer = ::OAuth::Consumer.new(oauth_token_key,
62
+ oauth_token_secret,
63
+ :scheme => :query_string,
64
+ :http_method => :get,
65
+ :site => OAUTH_SITES[site],
66
+ :request_token_path => OAUTH_REQUEST_TOKEN_URL,
67
+ :access_token_path => OAUTH_ACCESS_TOKEN_URL,
68
+ :authorize_path => OAUTH_AUTHORIZATION_URL)
69
+
70
+ if params[:application_type] == APPLICATION_TYPE_ONSITE
71
+ @access_token = ::OAuth::AccessToken.new(@consumer, "", "")
72
+ elsif params[:access_token]
73
+ @access_token = ::OAuth::AccessToken.new(@consumer,
74
+ params[:access_token],
75
+ params[:access_token_secret])
76
+ end
77
+ if params[:request_token]
78
+ @request_token = ::OAuth::RequestToken.new(@consumer,
79
+ params[:request_token],
80
+ params[:request_token_secret])
81
+ end
82
+ end
83
+
84
+ # Get an unauthorized request token from MySpace.
85
+ def get_request_token
86
+ @consumer.get_request_token
87
+ end
88
+
89
+ # Get the url to which to redirect the user in order to authorize
90
+ # our access to their account. This url will redirect back to
91
+ # +callback_url+ once the user authorizes us.
92
+ def get_authorization_url(request_token, callback_url)
93
+ "#{request_token.authorize_url}&oauth_callback=#{CGI::escape(callback_url)}"
94
+ end
95
+
96
+ # Get an access token once the user has authorized us.
97
+ def get_access_token(request_token = @request_token)
98
+ # response = @consumer.token_request(@consumer.http_method,
99
+ # (@consumer.access_token_url? ? @consumer.access_token_url : @consumer.access_token_path),
100
+ # request_token,
101
+ # {},
102
+ # headers)
103
+
104
+ # @access_token = ::OAuth::AccessToken.new(@consumer, response[:oauth_token], response[:oauth_token_secret])
105
+ @access_token = request_token.get_access_token
106
+ end
107
+
108
+ # Get the user id of the currently logged in user.
109
+ def get_userid()
110
+ user_info = call_myspace_api_json(API_USERINFO_URL)
111
+ user_info['userId'].to_s
112
+ end
113
+
114
+ # Get the photo album descriptions for the user +user_id+:
115
+ #
116
+ # {"albums"=>
117
+ # [{"photosUri"=>
118
+ # "http://api.myspace.com/v1/users/456073223/albums/40418/photos",
119
+ # "photoCount"=>1,
120
+ # "location"=>"",
121
+ # "title"=>"My Photos",
122
+ # "id"=>40418,
123
+ # "defaultImage"=>
124
+ # "http://c1.ac-images.myspacecdn.com/images02/45/m_f820313641924f0f90004932c8bc310c.jpg",
125
+ # "privacy"=>"Everyone",
126
+ # "user"=>
127
+ # {"name"=>"Bob",
128
+ # "uri"=>"http://api.myspace.com/v1/users/456073223",
129
+ # "webUri"=>"http://www.myspace.com/bobvontestacount",
130
+ # "largeImage"=>
131
+ # "http://c1.ac-images.myspacecdn.com/images02/45/l_f820313641924f0f90004932c8bc310c.jpg",
132
+ # "userType"=>"RegularUser",
133
+ # "userId"=>456073223,
134
+ # "image"=>
135
+ # "http://c1.ac-images.myspacecdn.com/images02/45/s_f820313641924f0f90004932c8bc310c.jpg"},
136
+ # "albumUri"=>"http://api.myspace.com/v1/users/456073223/albums/40418"}],
137
+ # "count"=>1,
138
+ # "user"=>
139
+ # {"name"=>"Bob",
140
+ # "uri"=>"http://api.myspace.com/v1/users/456073223",
141
+ # "webUri"=>"http://www.myspace.com/bobvontestacount",
142
+ # "largeImage"=>
143
+ # "http://c1.ac-images.myspacecdn.com/images02/45/l_f820313641924f0f90004932c8bc310c.jpg",
144
+ # "userType"=>"RegularUser",
145
+ # "userId"=>456073223,
146
+ # "image"=>
147
+ # "http://c1.ac-images.myspacecdn.com/images02/45/s_f820313641924f0f90004932c8bc310c.jpg"}}
148
+ def get_albums(user_id, params = {})
149
+ user_id = user_id.to_s
150
+ validate_identifier(:user_id, user_id)
151
+ url = sprintf(API_ALBUMS_URL, user_id)
152
+ call_myspace_api_json(url, :get, params)
153
+ end
154
+
155
+ # Get the photo descriptions for the photos of album +album_id+
156
+ # for the user +user_id+:
157
+ #
158
+ # {"photos"=>
159
+ # [{"smallImageUri"=>
160
+ # "http://c1.ac-images.myspacecdn.com/images02/45/s_f820313641924f0f90004932c8bc310c.jpg",
161
+ # "photoUri"=>
162
+ # "http://api.myspace.com/v1/users/456073223/albums/40418/photos/100809",
163
+ # "id"=>100809,
164
+ # "uploadDate"=>"2/27/2009 10:14:12 AM",
165
+ # "caption"=>"",
166
+ # "lastUpdatedDate"=>"",
167
+ # "imageUri"=>
168
+ # "http://c1.ac-images.myspacecdn.com/images02/45/l_f820313641924f0f90004932c8bc310c.jpg",
169
+ # "user"=>
170
+ # {"name"=>"Bob",
171
+ # "uri"=>"http://api.myspace.com/v1/users/456073223",
172
+ # "webUri"=>"http://www.myspace.com/bobvontestacount",
173
+ # "largeImage"=>
174
+ # "http://c1.ac-images.myspacecdn.com/images02/45/l_f820313641924f0f90004932c8bc310c.jpg",
175
+ # "userType"=>"RegularUser",
176
+ # "userId"=>456073223,
177
+ # "image"=>
178
+ # "http://c1.ac-images.myspacecdn.com/images02/45/s_f820313641924f0f90004932c8bc310c.jpg"}}],
179
+ # "count"=>1,
180
+ # "user"=>
181
+ # {"name"=>"Bob",
182
+ # "uri"=>"http://api.myspace.com/v1/users/456073223",
183
+ # "webUri"=>"http://www.myspace.com/bobvontestacount",
184
+ # "largeImage"=>
185
+ # "http://c1.ac-images.myspacecdn.com/images02/45/l_f820313641924f0f90004932c8bc310c.jpg",
186
+ # "userType"=>"RegularUser",
187
+ # "userId"=>456073223,
188
+ # "image"=>
189
+ # "http://c1.ac-images.myspacecdn.com/images02/45/s_f820313641924f0f90004932c8bc310c.jpg"}}
190
+ def get_album(user_id, album_id)
191
+ user_id = user_id.to_s
192
+ validate_identifier(:user_id, user_id)
193
+ album_id = album_id.to_s
194
+ validate_identifier(:album_id, album_id)
195
+ url = sprintf(API_ALBUM_URL, user_id, album_id)
196
+ call_myspace_api_json(url)
197
+ end
198
+
199
+ # Gets the list of friends for the user +user_id+:
200
+ #
201
+ # {"topFriends"=>"http://api.myspace.com/v1/users/456073223/friends?list=top",
202
+ # "Friends"=>
203
+ # [{"name"=>"Tom",
204
+ # "uri"=>"http://api.myspace.com/v1/users/6221",
205
+ # "webUri"=>"http://www.myspace.com/tom",
206
+ # "largeImage"=>"http://b2.ac-images.myspacecdn.com/00000/20/52/2502_l.jpg",
207
+ # "userType"=>"RegularUser",
208
+ # "userId"=>6221,
209
+ # "image"=>"http://b2.ac-images.myspacecdn.com/00000/20/52/2502_s.jpg"}],
210
+ # "count"=>1,
211
+ # "user"=>
212
+ # {"name"=>"Bob",
213
+ # "uri"=>"http://api.myspace.com/v1/users/456073223",
214
+ # "webUri"=>"http://www.myspace.com/bobvontestacount",
215
+ # "largeImage"=>
216
+ # "http://c1.ac-images.myspacecdn.com/images02/45/l_f820313641924f0f90004932c8bc310c.jpg",
217
+ # "userType"=>"RegularUser",
218
+ # "userId"=>456073223,
219
+ # "image"=>
220
+ # "http://c1.ac-images.myspacecdn.com/images02/45/s_f820313641924f0f90004932c8bc310c.jpg"}}
221
+ def get_friends(user_id, params = {})
222
+ user_id = user_id.to_s
223
+ validate_identifier(:user_id, user_id)
224
+ url = sprintf(API_FRIENDS_URL, user_id)
225
+ call_myspace_api_json(url, :get, params)
226
+ end
227
+
228
+ # Tests whether user +user_id+ is friends with one or more other users:
229
+ #
230
+ # {"friendship"=>
231
+ # [{"areFriends"=>true, "friendId"=>6221},
232
+ # {"areFriends"=>false, "friendId"=>12341234},
233
+ # {"areFriends"=>true, "friendId"=>456073223}],
234
+ # "user"=>
235
+ # {"name"=>"Bob",
236
+ # "uri"=>"http://api.myspace.com/v1/users/456073223",
237
+ # "webUri"=>"http://www.myspace.com/bobvontestacount",
238
+ # "largeImage"=>
239
+ # "http://c1.ac-images.myspacecdn.com/images02/45/l_f820313641924f0f90004932c8bc310c.jpg",
240
+ # "userType"=>"RegularUser",
241
+ # "userId"=>456073223,
242
+ # "image"=>
243
+ # "http://c1.ac-images.myspacecdn.com/images02/45/s_f820313641924f0f90004932c8bc310c.jpg"}}
244
+ def get_friendship(user_id, *friend_ids)
245
+ user_id = user_id.to_s
246
+ validate_identifier(:user_id, user_id)
247
+ friend_ids.each do |friend_id|
248
+ friend_id = friend_id.to_s
249
+ validate_identifier(:friend_ids, friend_id)
250
+ end
251
+ url = sprintf(API_FRIENDSHIP_URL, user_id, friend_ids.join(';'))
252
+ call_myspace_api_json(url)
253
+ end
254
+
255
+ # Gets the mood of user +user_id+:
256
+ #
257
+ # {"mood"=>"tested",
258
+ # "moodImageUrl"=>
259
+ # "http://x.myspacecdn.com/images/blog/moods/iBrads/indescribable.gif",
260
+ # "moodLastUpdated"=>"2/27/2009 10:19:25 AM",
261
+ # "user"=>
262
+ # {"name"=>"Bob",
263
+ # "uri"=>"http://api.myspace.com/v1/users/456073223",
264
+ # "webUri"=>"http://www.myspace.com/bobvontestacount",
265
+ # "largeImage"=>
266
+ # "http://c1.ac-images.myspacecdn.com/images02/45/l_f820313641924f0f90004932c8bc310c.jpg",
267
+ # "userType"=>"RegularUser",
268
+ # "userId"=>456073223,
269
+ # "image"=>
270
+ # "http://c1.ac-images.myspacecdn.com/images02/45/s_f820313641924f0f90004932c8bc310c.jpg"}}
271
+ def get_mood(user_id)
272
+ user_id = user_id.to_s
273
+ validate_identifier(:user_id, user_id)
274
+ url = sprintf(API_MOOD_URL, user_id)
275
+ call_myspace_api_json(url)
276
+ end
277
+
278
+ # Gets the photo descriptions for the photos that belong to user +user_id+:
279
+ #
280
+ # {"photos"=>
281
+ # [{"smallImageUri"=>
282
+ # "http://c1.ac-images.myspacecdn.com/images02/45/s_f820313641924f0f90004932c8bc310c.jpg",
283
+ # "photoUri"=>"http://api.myspace.com/v1/users/456073223/photos/100809",
284
+ # "id"=>100809,
285
+ # "uploadDate"=>"2/27/2009 10:14:12 AM",
286
+ # "caption"=>"",
287
+ # "lastUpdatedDate"=>"",
288
+ # "imageUri"=>
289
+ # "http://c1.ac-images.myspacecdn.com/images02/45/l_f820313641924f0f90004932c8bc310c.jpg",
290
+ # "user"=>
291
+ # {"name"=>"Bob",
292
+ # "uri"=>"http://api.myspace.com/v1/users/456073223",
293
+ # "webUri"=>"http://www.myspace.com/bobvontestacount",
294
+ # "largeImage"=>
295
+ # "http://c1.ac-images.myspacecdn.com/images02/45/l_f820313641924f0f90004932c8bc310c.jpg",
296
+ # "userType"=>"RegularUser",
297
+ # "userId"=>456073223,
298
+ # "image"=>
299
+ # "http://c1.ac-images.myspacecdn.com/images02/45/s_f820313641924f0f90004932c8bc310c.jpg"}}],
300
+ # "count"=>1,
301
+ # "user"=>
302
+ # {"name"=>"Bob",
303
+ # "uri"=>"http://api.myspace.com/v1/users/456073223",
304
+ # "webUri"=>"http://www.myspace.com/bobvontestacount",
305
+ # "largeImage"=>
306
+ # "http://c1.ac-images.myspacecdn.com/images02/45/l_f820313641924f0f90004932c8bc310c.jpg",
307
+ # "userType"=>"RegularUser",
308
+ # "userId"=>456073223,
309
+ # "image"=>
310
+ # "http://c1.ac-images.myspacecdn.com/images02/45/s_f820313641924f0f90004932c8bc310c.jpg"}}
311
+ def get_photos(user_id, params = {})
312
+ user_id = user_id.to_s
313
+ validate_identifier(:user_id, user_id)
314
+ url = sprintf(API_PHOTOS_URL, user_id)
315
+ call_myspace_api_json(url, :get, params)
316
+ end
317
+
318
+ # Gets the photo description for photo +photo_id+ for user +user_id+:
319
+ #
320
+ # {"smallImageUri"=>
321
+ # "http://c1.ac-images.myspacecdn.com/images02/45/s_f820313641924f0f90004932c8bc310c.jpg",
322
+ # "photoUri"=>"http://api.myspace.com/v1/users/456073223/photos/100809",
323
+ # "id"=>100809,
324
+ # "uploadDate"=>"2/27/2009 10:14:12 AM",
325
+ # "caption"=>"",
326
+ # "lastUpdatedDate"=>"",
327
+ # "imageUri"=>
328
+ # "http://c1.ac-images.myspacecdn.com/images02/45/l_f820313641924f0f90004932c8bc310c.jpg",
329
+ # "user"=>
330
+ # {"name"=>"Bob",
331
+ # "uri"=>"http://api.myspace.com/v1/users/456073223",
332
+ # "webUri"=>"http://www.myspace.com/bobvontestacount",
333
+ # "largeImage"=>
334
+ # "http://c1.ac-images.myspacecdn.com/images02/45/l_f820313641924f0f90004932c8bc310c.jpg",
335
+ # "userType"=>"RegularUser",
336
+ # "userId"=>456073223,
337
+ # "image"=>
338
+ # "http://c1.ac-images.myspacecdn.com/images02/45/s_f820313641924f0f90004932c8bc310c.jpg"}}
339
+ def get_photo(user_id, photo_id)
340
+ user_id = user_id.to_s
341
+ validate_identifier(:user_id, user_id)
342
+ photo_id = photo_id.to_s
343
+ validate_identifier(:photo_id, photo_id)
344
+ url = sprintf(API_PHOTO_URL, user_id, photo_id)
345
+ call_myspace_api_json(url)
346
+ end
347
+
348
+ # Gets the profile info for user +user_id+:
349
+ #
350
+ # {"region"=>"California",
351
+ # "city"=>"BEVERLY HILLS",
352
+ # "country"=>"US",
353
+ # "postalcode"=>"90210",
354
+ # "gender"=>"Male",
355
+ # "type"=>"full",
356
+ # "culture"=>"en-US",
357
+ # "aboutme"=>"",
358
+ # "hometown"=>"",
359
+ # "basicprofile"=>
360
+ # {"name"=>"Bob",
361
+ # "uri"=>"http://api.myspace.com/v1/users/456073223",
362
+ # "webUri"=>"http://www.myspace.com/bobvontestacount",
363
+ # "largeImage"=>
364
+ # "http://c1.ac-images.myspacecdn.com/images02/45/l_f820313641924f0f90004932c8bc310c.jpg",
365
+ # "userId"=>456073223,
366
+ # "lastUpdatedDate"=>"2/27/2009 10:20:02 AM",
367
+ # "image"=>
368
+ # "http://c1.ac-images.myspacecdn.com/images02/45/s_f820313641924f0f90004932c8bc310c.jpg"},
369
+ # "age"=>88,
370
+ # "maritalstatus"=>"Single"}
371
+ def get_profile(user_id, params = {})
372
+ user_id = user_id.to_s
373
+ validate_identifier(:user_id, user_id)
374
+ url = sprintf(API_PROFILE_URL, user_id)
375
+ call_myspace_api_json(url, :get, params)
376
+ end
377
+
378
+ # Gets the status of user +user_id+:
379
+ #
380
+ # {"mood"=>"tested",
381
+ # "moodImageUrl"=>
382
+ # "http://x.myspacecdn.com/images/blog/moods/iBrads/indescribable.gif",
383
+ # "moodLastUpdated"=>"2/27/2009 10:19:25 AM",
384
+ # "user"=>
385
+ # {"name"=>"Bob",
386
+ # "uri"=>"http://api.myspace.com/v1/users/456073223",
387
+ # "webUri"=>"http://www.myspace.com/bobvontestacount",
388
+ # "largeImage"=>
389
+ # "http://c1.ac-images.myspacecdn.com/images02/45/l_f820313641924f0f90004932c8bc310c.jpg",
390
+ # "userType"=>"RegularUser",
391
+ # "userId"=>456073223,
392
+ # "image"=>
393
+ # "http://c1.ac-images.myspacecdn.com/images02/45/s_f820313641924f0f90004932c8bc310c.jpg"},
394
+ # "status"=>"Testing"}
395
+ def get_status(user_id)
396
+ user_id = user_id.to_s
397
+ validate_identifier(:user_id, user_id)
398
+ url = sprintf(API_STATUS_URL, user_id)
399
+ call_myspace_api_json(url)
400
+ end
401
+
402
+ # Gets the video descriptions for the videos of user +user_id+:
403
+ #
404
+ # {"videos"=>
405
+ # [{"totalrating"=>"0",
406
+ # "title"=>"110403na",
407
+ # "resourceuserid"=>"456073223",
408
+ # "mediastatus"=>"ProcessingSuccessful",
409
+ # "dateupdated"=>"3/5/2009 11:24:23 AM",
410
+ # "country"=>"US",
411
+ # "totalviews"=>"0",
412
+ # "thumbnail"=>
413
+ # "http://d4.ac-videos.myspacecdn.com/videos02/8/thumb1_1bd4f5fde59540c2981c35b27c15a0f3.jpg",
414
+ # "language"=>"en",
415
+ # "id"=>53551799,
416
+ # "totalcomments"=>"0",
417
+ # "runtime"=>"219",
418
+ # "datecreated"=>"3/5/2009 11:24:23 AM",
419
+ # "privacy"=>"Public",
420
+ # "mediatype"=>"4",
421
+ # "description"=>"110403na",
422
+ # "user"=>
423
+ # {"name"=>"Bob",
424
+ # "uri"=>"http://api.myspace.com/v1/users/456073223",
425
+ # "webUri"=>"http://www.myspace.com/bobvontestacount",
426
+ # "largeImage"=>
427
+ # "http://c1.ac-images.myspacecdn.com/images02/45/l_f820313641924f0f90004932c8bc310c.jpg",
428
+ # "userType"=>"RegularUser",
429
+ # "userId"=>456073223,
430
+ # "image"=>
431
+ # "http://c1.ac-images.myspacecdn.com/images02/45/s_f820313641924f0f90004932c8bc310c.jpg"},
432
+ # "totalvotes"=>"0",
433
+ # "videoUri"=>"http://api.myspace.com/v1/users/456073223/videos/53551799"}],
434
+ # "count"=>1,
435
+ # "user"=>
436
+ # {"name"=>"Bob",
437
+ # "uri"=>"http://api.myspace.com/v1/users/456073223",
438
+ # "webUri"=>"http://www.myspace.com/bobvontestacount",
439
+ # "largeImage"=>
440
+ # "http://c1.ac-images.myspacecdn.com/images02/45/l_f820313641924f0f90004932c8bc310c.jpg",
441
+ # "userType"=>"RegularUser",
442
+ # "userId"=>456073223,
443
+ # "image"=>
444
+ # "http://c1.ac-images.myspacecdn.com/images02/45/s_f820313641924f0f90004932c8bc310c.jpg"}}
445
+ def get_videos(user_id)
446
+ user_id = user_id.to_s
447
+ validate_identifier(:user_id, user_id)
448
+ url = sprintf(API_VIDEOS_URL, user_id)
449
+ call_myspace_api_json(url)
450
+ end
451
+
452
+ # Gets the video description for the video +video_id+ of user +user_id+:
453
+ #
454
+ # {"totalrating"=>"0",
455
+ # "title"=>"110403na",
456
+ # "resourceuserid"=>"456073223",
457
+ # "mediastatus"=>"ProcessingSuccessful",
458
+ # "dateupdated"=>"3/5/2009 11:24:23 AM",
459
+ # "country"=>"US",
460
+ # "totalviews"=>"0",
461
+ # "thumbnail"=>
462
+ # "http://d1.ac-videos.myspacecdn.com/videos02/8/thumb1_461592d881c14023bcb6a73275ebc614.jpg",
463
+ # "language"=>"en",
464
+ # "id"=>53551799,
465
+ # "totalcomments"=>"0",
466
+ # "runtime"=>"219",
467
+ # "datecreated"=>"3/5/2009 11:24:23 AM",
468
+ # "privacy"=>"Public",
469
+ # "mediatype"=>"4",
470
+ # "description"=>"110403na",
471
+ # "user"=>
472
+ # {"name"=>"Bob",
473
+ # "uri"=>"http://api.myspace.com/v1/users/456073223",
474
+ # "webUri"=>"http://www.myspace.com/bobvontestacount",
475
+ # "largeImage"=>
476
+ # "http://c1.ac-images.myspacecdn.com/images02/45/l_f820313641924f0f90004932c8bc310c.jpg",
477
+ # "userType"=>"RegularUser",
478
+ # "userId"=>456073223,
479
+ # "image"=>
480
+ # "http://c1.ac-images.myspacecdn.com/images02/45/s_f820313641924f0f90004932c8bc310c.jpg"},
481
+ # "totalvotes"=>"0",
482
+ # "videoUri"=>"http://api.myspace.com/v1/users/456073223/videos/53551799"}
483
+ def get_video(user_id, video_id)
484
+ user_id = user_id.to_s
485
+ validate_identifier(:user_id, user_id)
486
+ video_id = video_id.to_s
487
+ validate_identifier(:video_id, video_id)
488
+ url = sprintf(API_VIDEO_URL, user_id, video_id)
489
+ call_myspace_api_json(url)
490
+ end
491
+
492
+ def get_activities(user_id)
493
+ user_id = user_id.to_s
494
+ validate_identifier(:user_id, user_id)
495
+ url = sprintf(API_ACTIVITIES_URL, user_id)
496
+ call_myspace_api_xml(url)
497
+ end
498
+
499
+ def get_friends_activities(user_id)
500
+ user_id = user_id.to_s
501
+ validate_identifier(:user_id, user_id)
502
+ url = sprintf(API_FRIENDS_ACTIVITIES_URL, user_id)
503
+ call_myspace_api_xml(url)
504
+ end
505
+
506
+ def set_status(user_id, status)
507
+ user_id = user_id.to_s
508
+ validate_identifier(:user_id, user_id)
509
+ url = sprintf(API_STATUS_PUT_URL, user_id)
510
+ call_myspace_api_xml(url, :put, {:body => {:status => status}})
511
+ end
512
+
513
+ def call_myspace_api(url, method = :get, params = {}, &block)
514
+ params = params.dup
515
+ body = params.delete(:body)
516
+ headers = params.delete(:headers)
517
+ query_str = params.collect do |key, value|
518
+ CGI.escape(key.to_s) + '=' + CGI.escape(value.to_s)
519
+ end.join('&')
520
+
521
+ url << '?' + query_str if query_str.length > 0
522
+
523
+ @http_logger.info("sending: '#{url}'") if @http_logger
524
+ resp = @access_token.request(method, url, body, headers)
525
+ @http_logger.info("received: '#{resp.code}': '#{resp.body}'") if @http_logger
526
+
527
+ validate_response(resp, url)
528
+ yield(resp.body)
529
+ end
530
+
531
+ def call_myspace_api_json(url, method = :get, params = {})
532
+ call_myspace_api(url, method, params) do |body|
533
+ JSON::parse(body)
534
+ end
535
+ end
536
+
537
+ def call_myspace_api_xml(url, method = :get, params = {})
538
+ call_myspace_api(url, method, params) do |body|
539
+ REXML::Document.new(body)
540
+ end
541
+ end
542
+
543
+ protected
544
+
545
+ ID_REGEXP = /[0-9]+/ unless const_defined?('ID_REGEXP')
546
+
547
+ def validate_identifier(parameter, identifier)
548
+ raise BadIdentifier.new(parameter, identifier) unless identifier && identifier =~ ID_REGEXP
549
+ end
550
+
551
+ def validate_response(response, url)
552
+ code = response.code
553
+ case code
554
+ when '200'
555
+ return
556
+ when '201'
557
+ return
558
+ when '401'
559
+ raise PermissionDenied.new(code, response.message, url)
560
+ else
561
+ raise RestException.new(code, response.message, url) unless ['200', '201'].include?(code)
562
+ end
563
+ end
564
+ end
565
+ end