tenderlove-facebooker 1.0.16.20090319151701

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