taweili-facebooker 1.0.37

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 (135) hide show
  1. data/.autotest +15 -0
  2. data/CHANGELOG.rdoc +24 -0
  3. data/COPYING.rdoc +19 -0
  4. data/Manifest.txt +133 -0
  5. data/README.rdoc +104 -0
  6. data/Rakefile +85 -0
  7. data/TODO.rdoc +4 -0
  8. data/examples/desktop_login.rb +14 -0
  9. data/facebooker.gemspec +38 -0
  10. data/generators/facebook/facebook_generator.rb +14 -0
  11. data/generators/facebook/templates/config/facebooker.yml +49 -0
  12. data/generators/facebook/templates/public/javascripts/facebooker.js +83 -0
  13. data/generators/facebook_controller/USAGE +33 -0
  14. data/generators/facebook_controller/facebook_controller_generator.rb +40 -0
  15. data/generators/facebook_controller/templates/controller.rb +7 -0
  16. data/generators/facebook_controller/templates/functional_test.rb +11 -0
  17. data/generators/facebook_controller/templates/helper.rb +2 -0
  18. data/generators/facebook_controller/templates/view.fbml.erb +2 -0
  19. data/generators/facebook_controller/templates/view.html.erb +2 -0
  20. data/generators/facebook_publisher/facebook_publisher_generator.rb +14 -0
  21. data/generators/facebook_publisher/templates/create_facebook_templates.rb +15 -0
  22. data/generators/facebook_publisher/templates/publisher.rb +3 -0
  23. data/generators/facebook_scaffold/USAGE +27 -0
  24. data/generators/facebook_scaffold/facebook_scaffold_generator.rb +118 -0
  25. data/generators/facebook_scaffold/templates/controller.rb +93 -0
  26. data/generators/facebook_scaffold/templates/facebook_style.css +2579 -0
  27. data/generators/facebook_scaffold/templates/functional_test.rb +89 -0
  28. data/generators/facebook_scaffold/templates/helper.rb +2 -0
  29. data/generators/facebook_scaffold/templates/layout.fbml.erb +6 -0
  30. data/generators/facebook_scaffold/templates/layout.html.erb +17 -0
  31. data/generators/facebook_scaffold/templates/style.css +74 -0
  32. data/generators/facebook_scaffold/templates/view_edit.fbml.erb +13 -0
  33. data/generators/facebook_scaffold/templates/view_edit.html.erb +18 -0
  34. data/generators/facebook_scaffold/templates/view_index.fbml.erb +24 -0
  35. data/generators/facebook_scaffold/templates/view_index.html.erb +24 -0
  36. data/generators/facebook_scaffold/templates/view_new.fbml.erb +12 -0
  37. data/generators/facebook_scaffold/templates/view_new.html.erb +17 -0
  38. data/generators/facebook_scaffold/templates/view_show.fbml.erb +10 -0
  39. data/generators/facebook_scaffold/templates/view_show.html.erb +10 -0
  40. data/generators/publisher/publisher_generator.rb +14 -0
  41. data/generators/xd_receiver/templates/xd_receiver.html +10 -0
  42. data/generators/xd_receiver/xd_receiver_generator.rb +10 -0
  43. data/init.rb +25 -0
  44. data/install.rb +12 -0
  45. data/lib/facebooker/adapters/adapter_base.rb +91 -0
  46. data/lib/facebooker/adapters/bebo_adapter.rb +77 -0
  47. data/lib/facebooker/adapters/facebook_adapter.rb +52 -0
  48. data/lib/facebooker/admin.rb +42 -0
  49. data/lib/facebooker/batch_request.rb +45 -0
  50. data/lib/facebooker/data.rb +57 -0
  51. data/lib/facebooker/feed.rb +78 -0
  52. data/lib/facebooker/logging.rb +44 -0
  53. data/lib/facebooker/mobile.rb +20 -0
  54. data/lib/facebooker/mock/service.rb +50 -0
  55. data/lib/facebooker/mock/session.rb +18 -0
  56. data/lib/facebooker/model.rb +139 -0
  57. data/lib/facebooker/models/affiliation.rb +10 -0
  58. data/lib/facebooker/models/album.rb +11 -0
  59. data/lib/facebooker/models/applicationproperties.rb +39 -0
  60. data/lib/facebooker/models/applicationrestrictions.rb +10 -0
  61. data/lib/facebooker/models/cookie.rb +10 -0
  62. data/lib/facebooker/models/education_info.rb +11 -0
  63. data/lib/facebooker/models/event.rb +28 -0
  64. data/lib/facebooker/models/friend_list.rb +16 -0
  65. data/lib/facebooker/models/group.rb +36 -0
  66. data/lib/facebooker/models/info_item.rb +10 -0
  67. data/lib/facebooker/models/info_section.rb +10 -0
  68. data/lib/facebooker/models/location.rb +8 -0
  69. data/lib/facebooker/models/notifications.rb +17 -0
  70. data/lib/facebooker/models/page.rb +28 -0
  71. data/lib/facebooker/models/photo.rb +19 -0
  72. data/lib/facebooker/models/tag.rb +12 -0
  73. data/lib/facebooker/models/user.rb +497 -0
  74. data/lib/facebooker/models/video.rb +9 -0
  75. data/lib/facebooker/models/work_info.rb +10 -0
  76. data/lib/facebooker/parser.rb +650 -0
  77. data/lib/facebooker/rails/backwards_compatible_param_checks.rb +31 -0
  78. data/lib/facebooker/rails/controller.rb +337 -0
  79. data/lib/facebooker/rails/cucumber/world.rb +46 -0
  80. data/lib/facebooker/rails/cucumber.rb +28 -0
  81. data/lib/facebooker/rails/extensions/action_controller.rb +48 -0
  82. data/lib/facebooker/rails/extensions/rack_setup.rb +6 -0
  83. data/lib/facebooker/rails/extensions/routing.rb +15 -0
  84. data/lib/facebooker/rails/facebook_form_builder.rb +112 -0
  85. data/lib/facebooker/rails/facebook_pretty_errors.rb +22 -0
  86. data/lib/facebooker/rails/facebook_request_fix.rb +30 -0
  87. data/lib/facebooker/rails/facebook_request_fix_2-3.rb +31 -0
  88. data/lib/facebooker/rails/facebook_session_handling.rb +68 -0
  89. data/lib/facebooker/rails/facebook_url_helper.rb +192 -0
  90. data/lib/facebooker/rails/facebook_url_rewriting.rb +60 -0
  91. data/lib/facebooker/rails/helpers/fb_connect.rb +118 -0
  92. data/lib/facebooker/rails/helpers.rb +780 -0
  93. data/lib/facebooker/rails/integration_session.rb +38 -0
  94. data/lib/facebooker/rails/profile_publisher_extensions.rb +42 -0
  95. data/lib/facebooker/rails/publisher.rb +554 -0
  96. data/lib/facebooker/rails/routing.rb +49 -0
  97. data/lib/facebooker/rails/test_helpers.rb +68 -0
  98. data/lib/facebooker/rails/utilities.rb +22 -0
  99. data/lib/facebooker/server_cache.rb +24 -0
  100. data/lib/facebooker/service.rb +102 -0
  101. data/lib/facebooker/session.rb +606 -0
  102. data/lib/facebooker/version.rb +9 -0
  103. data/lib/facebooker.rb +180 -0
  104. data/lib/net/http_multipart_post.rb +123 -0
  105. data/lib/rack/facebook.rb +77 -0
  106. data/lib/tasks/facebooker.rake +18 -0
  107. data/lib/tasks/tunnel.rake +46 -0
  108. data/rails/init.rb +1 -0
  109. data/setup.rb +1585 -0
  110. data/templates/layout.erb +24 -0
  111. data/test/facebooker/adapters_test.rb +96 -0
  112. data/test/facebooker/admin_test.rb +102 -0
  113. data/test/facebooker/batch_request_test.rb +83 -0
  114. data/test/facebooker/data_test.rb +86 -0
  115. data/test/facebooker/logging_test.rb +43 -0
  116. data/test/facebooker/mobile_test.rb +45 -0
  117. data/test/facebooker/model_test.rb +133 -0
  118. data/test/facebooker/models/event_test.rb +15 -0
  119. data/test/facebooker/models/photo_test.rb +16 -0
  120. data/test/facebooker/models/user_test.rb +343 -0
  121. data/test/facebooker/rails/facebook_request_fix_2-3_test.rb +24 -0
  122. data/test/facebooker/rails/facebook_url_rewriting_test.rb +39 -0
  123. data/test/facebooker/rails/publisher_test.rb +481 -0
  124. data/test/facebooker/rails_integration_test.rb +1398 -0
  125. data/test/facebooker/server_cache_test.rb +44 -0
  126. data/test/facebooker/session_test.rb +614 -0
  127. data/test/facebooker_test.rb +951 -0
  128. data/test/fixtures/multipart_post_body_with_only_parameters.txt +33 -0
  129. data/test/fixtures/multipart_post_body_with_single_file.txt +38 -0
  130. data/test/fixtures/multipart_post_body_with_single_file_that_has_nil_key.txt +38 -0
  131. data/test/net/http_multipart_post_test.rb +52 -0
  132. data/test/rack/facebook_test.rb +61 -0
  133. data/test/rails_test_helper.rb +27 -0
  134. data/test/test_helper.rb +74 -0
  135. metadata +232 -0
@@ -0,0 +1,650 @@
1
+ require 'rexml/document'
2
+ require 'facebooker/session'
3
+
4
+ module Facebooker
5
+ class Parser
6
+
7
+ module REXMLElementExtensions # :nodoc:
8
+ def content
9
+ self.text || ''
10
+ end
11
+
12
+ def [] key
13
+ attributes[key]
14
+ end
15
+
16
+ def text?
17
+ false
18
+ end
19
+ end
20
+
21
+ module REXMLTextExtensions # :nodoc:
22
+ def text?
23
+ true
24
+ end
25
+ end
26
+
27
+ ::REXML::Element.__send__(:include, REXMLElementExtensions)
28
+ ::REXML::Text.__send__(:include, REXMLTextExtensions)
29
+
30
+ def self.parse(method, data)
31
+ Errors.process(data)
32
+ parser = Parser::PARSERS[method]
33
+ raise "Can't find a parser for '#{method}'" unless parser
34
+ parser.process(data)
35
+ end
36
+
37
+ def self.array_of(response_element, element_name)
38
+ values_to_return = []
39
+ response_element.children.each do |element|
40
+ next if element.text?
41
+ next unless element.name == element_name
42
+ values_to_return << yield(element)
43
+ end
44
+ values_to_return
45
+ end
46
+
47
+ def self.array_of_text_values(response_element, element_name)
48
+ array_of(response_element, element_name) do |element|
49
+ element.content.strip
50
+ end
51
+ end
52
+
53
+ def self.array_of_hashes(response_element, element_name)
54
+ array_of(response_element, element_name) do |element|
55
+ hashinate(element)
56
+ end
57
+ end
58
+
59
+ def self.element(name, data)
60
+ data = data.body rescue data # either data or an HTTP response
61
+ begin
62
+ node = Nokogiri::XML(data.strip).at(name)
63
+ return node if node
64
+ rescue # Can't parse with Nokogiri
65
+ doc = REXML::Document.new(data)
66
+ doc.elements.each(name) do |element|
67
+ return element
68
+ end
69
+ end
70
+ raise "Element #{name} not found in #{data}"
71
+ end
72
+
73
+ def self.hash_or_value_for(element)
74
+ if element.children.size == 1 && element.children.first.text?
75
+ element.content.strip
76
+ else
77
+ hashinate(element)
78
+ end
79
+ end
80
+
81
+ def self.hashinate(response_element)
82
+ response_element.children.reject{|c| c.text? }.inject({}) do |hash, child|
83
+ # If the node hasn't any child, and is not a list, we want empty strings, not empty hashes,
84
+ # except if attributes['nil'] == true
85
+ hash[child.name] =
86
+ if (child['nil'] == 'true')
87
+ nil
88
+ elsif (child.children.size == 1 && child.children.first.text?) || (child.children.size == 0 && child['list'] != 'true')
89
+ anonymous_field_from(child, hash) || child.content.strip
90
+ elsif child['list'] == 'true'
91
+ child.children.reject{|c| c.text? }.map { |subchild| hash_or_value_for(subchild)}
92
+ else
93
+ child.children.reject{|c| c.text? }.inject({}) do |subhash, subchild|
94
+ subhash[subchild.name] = hash_or_value_for(subchild)
95
+ subhash
96
+ end
97
+ end #if (child.attributes)
98
+ hash
99
+ end #do |hash, child|
100
+ end
101
+
102
+ def self.booleanize(response)
103
+ response == "1" ? true : false
104
+ end
105
+
106
+ def self.anonymous_field_from(child, hash)
107
+ if child.name == 'anon'
108
+ (hash[child.name] || []) << child.content.strip
109
+ end
110
+ end
111
+
112
+ end
113
+
114
+ class RevokeAuthorization < Parser#:nodoc:
115
+ def self.process(data)
116
+ booleanize(data)
117
+ end
118
+ end
119
+
120
+ class CreateToken < Parser#:nodoc:
121
+ def self.process(data)
122
+ element('auth_createToken_response', data).content.strip
123
+ end
124
+ end
125
+
126
+ class RegisterUsers < Parser
127
+ def self.process(data)
128
+ array_of_text_values(element("connect_registerUsers_response", data), "connect_registerUsers_response_elt")
129
+ end
130
+ end
131
+
132
+ class UnregisterUsers < Parser
133
+ def self.process(data)
134
+ array_of_text_values(element("connect_unregisterUsers_response", data), "connect_unregisterUsers_response_elt")
135
+ end
136
+ end
137
+
138
+ class GetUnconnectedFriendsCount < Parser
139
+ def self.process(data)
140
+ hash_or_value_for(element("connect_getUnconnectedFriendsCount_response",data)).to_i
141
+ end
142
+ end
143
+
144
+ class GetSession < Parser#:nodoc:
145
+ def self.process(data)
146
+ hashinate(element('auth_getSession_response', data))
147
+ end
148
+ end
149
+
150
+ class GetFriends < Parser#:nodoc:
151
+ def self.process(data)
152
+ array_of_text_values(element('friends_get_response', data), 'uid')
153
+ end
154
+ end
155
+
156
+ class FriendListsGet < Parser#:nodoc:
157
+ def self.process(data)
158
+ array_of_hashes(element('friends_getLists_response', data), 'friendlist')
159
+ end
160
+ end
161
+
162
+ class UserInfo < Parser#:nodoc:
163
+ def self.process(data)
164
+ array_of_hashes(element('users_getInfo_response', data), 'user')
165
+ end
166
+ end
167
+
168
+ class UserStandardInfo < Parser#:nodoc:
169
+ def self.process(data)
170
+ array_of_hashes(element('users_getStandardInfo_response', data), 'standard_user_info')
171
+ end
172
+ end
173
+
174
+ class GetLoggedInUser < Parser#:nodoc:
175
+ def self.process(data)
176
+ Integer(element('users_getLoggedInUser_response', data).content.strip)
177
+ end
178
+ end
179
+
180
+ class PagesIsAdmin < Parser#:nodoc:
181
+ def self.process(data)
182
+ element('pages_isAdmin_response', data).content.strip == '1'
183
+ end
184
+ end
185
+
186
+ class PagesGetInfo < Parser#:nodoc:
187
+ def self.process(data)
188
+ array_of_hashes(element('pages_getInfo_response', data), 'page')
189
+ end
190
+ end
191
+
192
+ class PagesIsFan < Parser#:nodoc:
193
+ def self.process(data)
194
+ element('pages_isFan_response', data).content.strip == '1'
195
+ end
196
+ end
197
+
198
+ class PublishStoryToUser < Parser#:nodoc:
199
+ def self.process(data)
200
+ element('feed_publishStoryToUser_response', data).content.strip
201
+ end
202
+ end
203
+
204
+ class StreamPublish < Parser#:nodoc:
205
+ def self.process(data)
206
+ element('stream_publish_response', data).content.strip
207
+ end
208
+ end
209
+
210
+ class RegisterTemplateBundle < Parser#:nodoc:
211
+ def self.process(data)
212
+ element('feed_registerTemplateBundle_response', data).content.to_i
213
+ end
214
+ end
215
+
216
+ class GetRegisteredTemplateBundles < Parser
217
+ def self.process(data)
218
+ array_of_hashes(element('feed_getRegisteredTemplateBundles_response',data), 'template_bundle')
219
+ end
220
+ end
221
+
222
+ class DeactivateTemplateBundleByID < Parser#:nodoc:
223
+ def self.process(data)
224
+ element('feed_deactivateTemplateBundleByID_response', data).content.strip == '1'
225
+ end
226
+ end
227
+
228
+ class PublishUserAction < Parser#:nodoc:
229
+ def self.process(data)
230
+ element('feed_publishUserAction_response', data).children[1].content.strip == "1"
231
+ end
232
+ end
233
+
234
+ class PublishActionOfUser < Parser#:nodoc:
235
+ def self.process(data)
236
+ element('feed_publishActionOfUser_response', data).content.strip
237
+ end
238
+ end
239
+
240
+ class PublishTemplatizedAction < Parser#:nodoc:
241
+ def self.process(data)
242
+ element('feed_publishTemplatizedAction_response', data).children[1].content.strip
243
+ end
244
+ end
245
+
246
+ class SetAppProperties < Parser#:nodoc:
247
+ def self.process(data)
248
+ element('admin_setAppProperties_response', data).content.strip
249
+ end
250
+ end
251
+
252
+ class GetAppProperties < Parser#:nodoc:
253
+ def self.process(data)
254
+ element('admin_getAppProperties_response', data).content.strip
255
+ end
256
+ end
257
+
258
+ class SetRestrictionInfo < Parser#:nodoc:
259
+ def self.process(data)
260
+ element('admin_setRestrictionInfo_response', data).content.strip
261
+ end
262
+ end
263
+
264
+ class GetRestrictionInfo < Parser#:nodoc:
265
+ def self.process(data)
266
+ element('admin_getRestrictionInfo_response', data).content.strip
267
+ end
268
+ end
269
+
270
+ class GetAllocation < Parser#:nodoc:
271
+ def self.process(data)
272
+ element('admin_getAllocation_response', data).content.strip
273
+ end
274
+ end
275
+
276
+ class BatchRun < Parser #:nodoc:
277
+ class << self
278
+ def current_batch=(current_batch)
279
+ Thread.current[:facebooker_current_batch]=current_batch
280
+ end
281
+ def current_batch
282
+ Thread.current[:facebooker_current_batch]
283
+ end
284
+ end
285
+ def self.process(data)
286
+ array_of_text_values(element('batch_run_response',data),"batch_run_response_elt").each_with_index do |response,i|
287
+ batch_request=current_batch[i]
288
+ body=Struct.new(:body).new
289
+ body.body=CGI.unescapeHTML(response)
290
+ begin
291
+ batch_request.result=Parser.parse(batch_request.method,body)
292
+ rescue Exception=>ex
293
+ batch_request.exception_raised=ex
294
+ end
295
+ end
296
+ end
297
+ end
298
+
299
+ class GetAppUsers < Parser#:nodoc:
300
+ def self.process(data)
301
+ array_of_text_values(element('friends_getAppUsers_response', data), 'uid')
302
+ end
303
+ end
304
+
305
+ class NotificationsGet < Parser#:nodoc:
306
+ def self.process(data)
307
+ hashinate(element('notifications_get_response', data))
308
+ end
309
+ end
310
+
311
+ class NotificationsSend < Parser#:nodoc:
312
+ def self.process(data)
313
+ element('notifications_send_response', data).content.strip
314
+ end
315
+ end
316
+
317
+ class NotificationsSendEmail < Parser#:nodoc:
318
+ def self.process(data)
319
+ element('notifications_sendEmail_response', data).content.strip
320
+ end
321
+ end
322
+
323
+ class GetTags < Parser#nodoc:
324
+ def self.process(data)
325
+ array_of_hashes(element('photos_getTags_response', data), 'photo_tag')
326
+ end
327
+ end
328
+
329
+ class AddTags < Parser#nodoc:
330
+ def self.process(data)
331
+ element('photos_addTag_response', data)
332
+ end
333
+ end
334
+
335
+ class GetPhotos < Parser#nodoc:
336
+ def self.process(data)
337
+ array_of_hashes(element('photos_get_response', data), 'photo')
338
+ end
339
+ end
340
+
341
+ class GetAlbums < Parser#nodoc:
342
+ def self.process(data)
343
+ array_of_hashes(element('photos_getAlbums_response', data), 'album')
344
+ end
345
+ end
346
+
347
+ class CreateAlbum < Parser#:nodoc:
348
+ def self.process(data)
349
+ hashinate(element('photos_createAlbum_response', data))
350
+ end
351
+ end
352
+
353
+ class UploadPhoto < Parser#:nodoc:
354
+ def self.process(data)
355
+ hashinate(element('photos_upload_response', data))
356
+ end
357
+ end
358
+
359
+ class UploadVideo < Parser#:nodoc:
360
+ def self.process(data)
361
+ hashinate(element('video_upload_response', data))
362
+ end
363
+ end
364
+
365
+ class SendRequest < Parser#:nodoc:
366
+ def self.process(data)
367
+ element('notifications_sendRequest_response', data).content.strip
368
+ end
369
+ end
370
+
371
+ class ProfileFBML < Parser#:nodoc:
372
+ def self.process(data)
373
+ element('profile_getFBML_response', data).content.strip
374
+ end
375
+ end
376
+
377
+ class ProfileFBMLSet < Parser#:nodoc:
378
+ def self.process(data)
379
+ element('profile_setFBML_response', data).content.strip
380
+ end
381
+ end
382
+
383
+ class ProfileInfo < Parser#:nodoc:
384
+ def self.process(data)
385
+ hashinate(element('profile_getInfo_response info_fields', data))
386
+ end
387
+ end
388
+
389
+ class ProfileInfoSet < Parser#:nodoc:
390
+ def self.process(data)
391
+ element('profile_setInfo_response', data).content.strip
392
+ end
393
+ end
394
+
395
+ class FqlQuery < Parser#nodoc
396
+ def self.process(data)
397
+ root = element('fql_query_response', data)
398
+ first_child = root.children.reject{|c| c.text? }.first
399
+ first_child.nil? ? [] : [first_child.name, array_of_hashes(root, first_child.name)]
400
+ end
401
+ end
402
+
403
+ class SetRefHandle < Parser#:nodoc:
404
+ def self.process(data)
405
+ element('fbml_setRefHandle_response', data).content.strip
406
+ end
407
+ end
408
+
409
+ class RefreshRefURL < Parser#:nodoc:
410
+ def self.process(data)
411
+ element('fbml_refreshRefUrl_response', data).content.strip
412
+ end
413
+ end
414
+
415
+ class RefreshImgSrc < Parser#:nodoc:
416
+ def self.process(data)
417
+ element('fbml_refreshImgSrc_response', data).content.strip
418
+ end
419
+ end
420
+
421
+ class SetCookie < Parser#:nodoc:
422
+ def self.process(data)
423
+ element('data_setCookie_response', data).content.strip
424
+ end
425
+ end
426
+
427
+ class GetCookies < Parser#:nodoc:
428
+ def self.process(data)
429
+ array_of_hashes(element('data_getCookie_response', data), 'cookies')
430
+ end
431
+ end
432
+
433
+ class EventsRsvp < Parser#:nodoc:
434
+ def self.process(data)
435
+ element('events_rsvp_response', data).text_value
436
+ end
437
+ end
438
+
439
+ class EventsGet < Parser#:nodoc:
440
+ def self.process(data)
441
+ array_of_hashes(element('events_get_response', data), 'event')
442
+ end
443
+ end
444
+
445
+ class GroupGetMembers < Parser#:nodoc:
446
+ def self.process(data)
447
+ root = element('groups_getMembers_response', data)
448
+ result = ['members', 'admins', 'officers', 'not_replied'].map do |position|
449
+ array_of(root, position) {|element| element}.map do |element|
450
+ array_of_text_values(element, 'uid').map do |uid|
451
+ {:position => position}.merge(:uid => uid)
452
+ end
453
+ end
454
+ end.flatten
455
+ end
456
+ end
457
+
458
+ class EventMembersGet < Parser#:nodoc:
459
+ def self.process(data)
460
+ root = element('events_getMembers_response', data)
461
+ result = ['attending', 'declined', 'unsure', 'not_replied'].map do |rsvp_status|
462
+ array_of(root, rsvp_status) {|element| element}.map do |element|
463
+ array_of_text_values(element, 'uid').map do |uid|
464
+ {:rsvp_status => rsvp_status}.merge(:uid => uid)
465
+ end
466
+ end
467
+ end.flatten
468
+ end
469
+ end
470
+
471
+ class GroupsGet < Parser#:nodoc:
472
+ def self.process(data)
473
+ array_of_hashes(element('groups_get_response', data), 'group')
474
+ end
475
+ end
476
+
477
+ class AreFriends < Parser#:nodoc:
478
+ def self.process(data)
479
+ array_of_hashes(element('friends_areFriends_response', data), 'friend_info').inject({}) do |memo, hash|
480
+ memo[[Integer(hash['uid1']), Integer(hash['uid2'])].sort] = are_friends?(hash['are_friends'])
481
+ memo
482
+ end
483
+ end
484
+
485
+ private
486
+ def self.are_friends?(raw_value)
487
+ if raw_value == '1'
488
+ true
489
+ elsif raw_value == '0'
490
+ false
491
+ else
492
+ nil
493
+ end
494
+ end
495
+ end
496
+
497
+ class SetStatus < Parser
498
+ def self.process(data)
499
+ element('users_setStatus_response',data).content.strip == '1'
500
+ end
501
+ end
502
+
503
+ class GetPreference < Parser#:nodoc:
504
+ def self.process(data)
505
+ element('data_getUserPreference_response', data).content.strip
506
+ end
507
+ end
508
+
509
+ class SetPreference < Parser#:nodoc:
510
+ def self.process(data)
511
+ element('data_setUserPreference_response', data).content.strip
512
+ end
513
+ end
514
+
515
+ class UserHasPermission < Parser
516
+ def self.process(data)
517
+ element('users_hasAppPermission_response', data).content.strip
518
+ end
519
+ end
520
+
521
+ class SmsSend < Parser#:nodoc:
522
+ def self.process(data)
523
+ element('sms_send_response', data).content.strip == '0'
524
+ end
525
+ end
526
+
527
+ class SmsCanSend < Parser#:nodoc:
528
+ def self.process(data)
529
+ element('sms_canSend_response', data).content.strip
530
+ end
531
+ end
532
+
533
+ class Errors < Parser#:nodoc:
534
+ EXCEPTIONS = {
535
+ 1 => Facebooker::Session::UnknownError,
536
+ 2 => Facebooker::Session::ServiceUnavailable,
537
+ 4 => Facebooker::Session::MaxRequestsDepleted,
538
+ 5 => Facebooker::Session::HostNotAllowed,
539
+ 100 => Facebooker::Session::MissingOrInvalidParameter,
540
+ 101 => Facebooker::Session::InvalidAPIKey,
541
+ 102 => Facebooker::Session::SessionExpired,
542
+ 103 => Facebooker::Session::CallOutOfOrder,
543
+ 104 => Facebooker::Session::IncorrectSignature,
544
+ 120 => Facebooker::Session::InvalidAlbumId,
545
+ 250 => Facebooker::Session::ExtendedPermissionRequired,
546
+ 321 => Facebooker::Session::AlbumIsFull,
547
+ 324 => Facebooker::Session::MissingOrInvalidImageFile,
548
+ 325 => Facebooker::Session::TooManyUnapprovedPhotosPending,
549
+ 330 => Facebooker::Session::TemplateDataMissingRequiredTokens,
550
+ 340 => Facebooker::Session::TooManyUserCalls,
551
+ 341 => Facebooker::Session::TooManyUserActionCalls,
552
+ 342 => Facebooker::Session::InvalidFeedTitleLink,
553
+ 343 => Facebooker::Session::InvalidFeedTitleLength,
554
+ 344 => Facebooker::Session::InvalidFeedTitleName,
555
+ 345 => Facebooker::Session::BlankFeedTitle,
556
+ 346 => Facebooker::Session::FeedBodyLengthTooLong,
557
+ 347 => Facebooker::Session::InvalidFeedPhotoSource,
558
+ 348 => Facebooker::Session::InvalidFeedPhotoLink,
559
+ 330 => Facebooker::Session::FeedMarkupInvalid,
560
+ 360 => Facebooker::Session::FeedTitleDataInvalid,
561
+ 361 => Facebooker::Session::FeedTitleTemplateInvalid,
562
+ 362 => Facebooker::Session::FeedBodyDataInvalid,
563
+ 363 => Facebooker::Session::FeedBodyTemplateInvalid,
564
+ 364 => Facebooker::Session::FeedPhotosNotRetrieved,
565
+ 366 => Facebooker::Session::FeedTargetIdsInvalid,
566
+ 601 => Facebooker::Session::FQLParseError,
567
+ 602 => Facebooker::Session::FQLFieldDoesNotExist,
568
+ 603 => Facebooker::Session::FQLTableDoesNotExist,
569
+ 604 => Facebooker::Session::FQLStatementNotIndexable,
570
+ 605 => Facebooker::Session::FQLFunctionDoesNotExist,
571
+ 606 => Facebooker::Session::FQLWrongNumberArgumentsPassedToFunction,
572
+ 807 => Facebooker::Session::TemplateBundleInvalid
573
+ }
574
+ def self.process(data)
575
+ response_element = element('error_response', data) rescue nil
576
+ if response_element
577
+ hash = hashinate(response_element)
578
+ exception = EXCEPTIONS[Integer(hash['error_code'])] || StandardError
579
+ raise exception, hash['error_msg']
580
+ end
581
+ end
582
+ end
583
+
584
+ class Parser
585
+ PARSERS = {
586
+ 'facebook.auth.revokeAuthorization' => RevokeAuthorization,
587
+ 'facebook.auth.createToken' => CreateToken,
588
+ 'facebook.auth.getSession' => GetSession,
589
+ 'facebook.connect.registerUsers' => RegisterUsers,
590
+ 'facebook.connect.unregisterUsers' => UnregisterUsers,
591
+ 'facebook.connect.getUnconnectedFriendsCount' => GetUnconnectedFriendsCount,
592
+ 'facebook.users.getInfo' => UserInfo,
593
+ 'facebook.users.getStandardInfo' => UserStandardInfo,
594
+ 'facebook.users.setStatus' => SetStatus,
595
+ 'facebook.users.getLoggedInUser' => GetLoggedInUser,
596
+ 'facebook.users.hasAppPermission' => UserHasPermission,
597
+ 'facebook.pages.isAdmin' => PagesIsAdmin,
598
+ 'facebook.pages.getInfo' => PagesGetInfo,
599
+ 'facebook.pages.isFan' => PagesIsFan,
600
+ 'facebook.friends.get' => GetFriends,
601
+ 'facebook.friends.getLists' => FriendListsGet,
602
+ 'facebook.friends.areFriends' => AreFriends,
603
+ 'facebook.friends.getAppUsers' => GetAppUsers,
604
+ 'facebook.feed.publishStoryToUser' => PublishStoryToUser,
605
+ 'facebook.feed.publishActionOfUser' => PublishActionOfUser,
606
+ 'facebook.feed.publishTemplatizedAction' => PublishTemplatizedAction,
607
+ 'facebook.feed.registerTemplateBundle' => RegisterTemplateBundle,
608
+ 'facebook.feed.deactivateTemplateBundleByID' => DeactivateTemplateBundleByID,
609
+ 'facebook.feed.getRegisteredTemplateBundles' => GetRegisteredTemplateBundles,
610
+ 'facebook.feed.publishUserAction' => PublishUserAction,
611
+ 'facebook.notifications.get' => NotificationsGet,
612
+ 'facebook.notifications.send' => NotificationsSend,
613
+ 'facebook.notifications.sendRequest' => SendRequest,
614
+ 'facebook.profile.getFBML' => ProfileFBML,
615
+ 'facebook.profile.setFBML' => ProfileFBMLSet,
616
+ 'facebook.profile.getInfo' => ProfileInfo,
617
+ 'facebook.profile.setInfo' => ProfileInfoSet,
618
+ 'facebook.fbml.setRefHandle' => SetRefHandle,
619
+ 'facebook.fbml.refreshRefUrl' => RefreshRefURL,
620
+ 'facebook.fbml.refreshImgSrc' => RefreshImgSrc,
621
+ 'facebook.data.setCookie' => SetCookie,
622
+ 'facebook.data.getCookies' => GetCookies,
623
+ 'facebook.admin.setAppProperties' => SetAppProperties,
624
+ 'facebook.admin.getAppProperties' => GetAppProperties,
625
+ 'facebook.admin.setRestrictionInfo' => SetRestrictionInfo,
626
+ 'facebook.admin.getRestrictionInfo' => GetRestrictionInfo,
627
+ 'facebook.admin.getAllocation' => GetAllocation,
628
+ 'facebook.batch.run' => BatchRun,
629
+ 'facebook.fql.query' => FqlQuery,
630
+ 'facebook.photos.get' => GetPhotos,
631
+ 'facebook.photos.getAlbums' => GetAlbums,
632
+ 'facebook.photos.createAlbum' => CreateAlbum,
633
+ 'facebook.photos.getTags' => GetTags,
634
+ 'facebook.photos.addTag' => AddTags,
635
+ 'facebook.photos.upload' => UploadPhoto,
636
+ 'facebook.stream.publish' => StreamPublish,
637
+ 'facebook.events.get' => EventsGet,
638
+ 'facebook.events.getMembers' => EventMembersGet,
639
+ 'facebook.events.rsvp' => EventsRsvp,
640
+ 'facebook.groups.get' => GroupsGet,
641
+ 'facebook.groups.getMembers' => GroupGetMembers,
642
+ 'facebook.notifications.sendEmail' => NotificationsSendEmail,
643
+ 'facebook.data.getUserPreference' => GetPreference,
644
+ 'facebook.data.setUserPreference' => SetPreference,
645
+ 'facebook.video.upload' => UploadVideo,
646
+ 'facebook.sms.send' => SmsSend,
647
+ 'facebook.sms.canSend' => SmsCanSend
648
+ }
649
+ end
650
+ end
@@ -0,0 +1,31 @@
1
+ module Facebooker::Rails::BackwardsCompatibleParamChecks
2
+
3
+ def one_or_true( value )
4
+ case value
5
+ when String then
6
+ value == "1"
7
+ when Numeric then
8
+ value.to_f == 1.0
9
+ when TrueClass then
10
+ true
11
+ else
12
+ false
13
+ end
14
+ end
15
+
16
+ def zero_or_false( value )
17
+ case value
18
+ when String then
19
+ value == "0"
20
+ when Numeric then
21
+ value.to_f == 0.0
22
+ when FalseClass then
23
+ true
24
+ when NilClass then
25
+ true
26
+ else
27
+ false
28
+ end
29
+ end
30
+
31
+ end