myspaceid-sdk 0.1.8

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