simianarmy-facebooker 1.0.40

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 +113 -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 +93 -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 +26 -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 +469 -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 +356 -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 +28 -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 +804 -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 +550 -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 +635 -0
  102. data/lib/facebooker/version.rb +9 -0
  103. data/lib/facebooker.rb +179 -0
  104. data/lib/net/http_multipart_post.rb +123 -0
  105. data/lib/rack/facebook.rb +82 -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 +174 -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 +361 -0
  121. data/test/facebooker/rails/facebook_request_fix_2-3_test.rb +25 -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 +1434 -0
  125. data/test/facebooker/server_cache_test.rb +44 -0
  126. data/test/facebooker/session_test.rb +652 -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 +222 -0
@@ -0,0 +1,17 @@
1
+ module Facebooker
2
+ class Notifications
3
+ include Model
4
+ attr_accessor :messages, :group_invites, :pokes, :friend_requests, :event_invites, :shares
5
+
6
+ [:Messages, :Pokes, :Shares].each do |notification_type|
7
+ const_set(notification_type, Class.new do
8
+ include Model
9
+ attr_accessor :unread, :most_recent
10
+ end)
11
+ attribute_name = "#{notification_type.to_s.downcase}"
12
+ define_method("#{attribute_name}=") do |value|
13
+ instance_variable_set("@#{attribute_name}", value.kind_of?(Hash) ? Notifications.const_get(notification_type).from_hash(value) : value)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,28 @@
1
+ require 'facebooker/model'
2
+ module Facebooker
3
+ class Page
4
+
5
+ class Genre
6
+ include Model
7
+ FIELDS = [ :dance, :party, :relax, :talk, :think, :workout, :sing, :intimate, :raunchy, :headphones ]
8
+ attr_accessor(*FIELDS)
9
+
10
+ def initialize(*args)
11
+ super
12
+
13
+ # convert '1'/'0' to true/false
14
+ FIELDS.each do |field|
15
+ self.send("#{field}=", self.send(field) == '1')
16
+ end
17
+ end
18
+ end
19
+
20
+ include Model
21
+ attr_accessor :page_id, :name, :pic_small, :pic_big, :pic_square, :pic_large, :type, :type, :website, :location, :hours, :band_members, :bio, :hometown, :record_label, :influences, :has_added_app, :founded, :company_overview, :mission, :products, :release_date, :starring, :written_by, :directed_by, :produced_by, :studio, :awards, :plot_outline, :network, :season, :schedule
22
+ attr_reader :genre
23
+
24
+ def genre=(value)
25
+ @genre = value.kind_of?(Hash) ? Genre.from_hash(value) : value
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,19 @@
1
+ require 'facebooker/model'
2
+ module Facebooker
3
+ class Photo
4
+ include Model
5
+ attr_accessor :aid, :owner, :title,
6
+ :link, :caption, :created,
7
+ :src, :src_big, :src_small,
8
+ :story_fbid
9
+
10
+ id_is :pid
11
+
12
+ #override the generated method for id_is to use a string
13
+ def pid=(val)
14
+ @pid = val
15
+ end
16
+
17
+ alias :id= :pid=
18
+ end
19
+ end
@@ -0,0 +1,12 @@
1
+ require 'facebooker/model'
2
+ module Facebooker
3
+ class Tag
4
+ include Model
5
+ attr_accessor :pid, :subject, :xcoord, :ycoord
6
+
7
+ def coordinates
8
+ [xcoord, ycoord]
9
+ end
10
+
11
+ end
12
+ end
@@ -0,0 +1,469 @@
1
+ require 'facebooker/model'
2
+ require 'facebooker/models/affiliation'
3
+ require 'facebooker/models/work_info'
4
+ module Facebooker
5
+ #
6
+ # Holds attributes and behavior for a Facebook User
7
+ class User
8
+ include Model
9
+ class Status
10
+ include Model
11
+ attr_accessor :message, :time, :status_id
12
+ end
13
+ FIELDS = [:political, :pic_small, :name, :quotes, :is_app_user, :tv, :profile_update_time, :meeting_sex, :hs_info, :timezone, :relationship_status, :hometown_location, :about_me, :wall_count, :significant_other_id, :pic_big, :music, :work_history, :sex, :religion, :notes_count, :activities, :pic_square, :movies, :has_added_app, :education_history, :birthday, :first_name, :meeting_for, :last_name, :interests, :current_location, :pic, :books, :affiliations, :locale, :profile_url, :proxied_email, :email_hashes, :allowed_restrictions, :pic_with_logo, :pic_big_with_logo, :pic_small_with_logo, :pic_square_with_logo]
14
+ STANDARD_FIELDS = [:uid, :first_name, :last_name, :name, :timezone, :birthday, :sex, :affiliations, :locale, :profile_url, :pic_square]
15
+ populating_attr_accessor(*FIELDS)
16
+ attr_reader :affiliations
17
+ populating_hash_settable_accessor :current_location, Location
18
+ populating_hash_settable_accessor :hometown_location, Location
19
+ populating_hash_settable_accessor :hs_info, EducationInfo::HighschoolInfo
20
+ populating_hash_settable_list_accessor :affiliations, Affiliation
21
+ populating_hash_settable_list_accessor :education_history, EducationInfo
22
+ populating_hash_settable_list_accessor :work_history, WorkInfo
23
+
24
+ populating_attr_reader :status
25
+
26
+ # Can pass in these two forms:
27
+ # id, session, (optional) attribute_hash
28
+ # attribute_hash
29
+ def initialize(*args)
30
+ @friends = nil
31
+ @current_location = nil
32
+ @pic = nil
33
+ @hometown_location = nil
34
+ @populated = false
35
+ @session = nil
36
+ @id = nil
37
+ if (args.first.kind_of?(String) || args.first.kind_of?(Integer)) && args.size==1
38
+ self.uid = args.shift
39
+ @session = Session.current
40
+ elsif (args.first.kind_of?(String) || args.first.kind_of?(Integer)) && args[1].kind_of?(Session)
41
+ self.uid = args.shift
42
+ @session = args.shift
43
+ end
44
+ if args.last.kind_of?(Hash)
45
+ populate_from_hash!(args.pop)
46
+ end
47
+ end
48
+
49
+ id_is :uid
50
+ alias :facebook_id :id
51
+
52
+ # Returns a user's events, params correspond to API call parameters (except UID):
53
+ # http://wiki.developers.facebook.com/index.php/Events.get
54
+ # E.g:
55
+ # @user.events(:start_time => Time.now, :end_time => 1.month.from_now)
56
+ # # => Returns events betwen now and a month from now
57
+ def events(params={})
58
+ @events ||= {}
59
+ [:start_time,:end_time].compact.each do |key|
60
+ params[key] = params[key].to_i
61
+ end
62
+ # puts @events[params.to_s].nil?
63
+ @events[params.to_s] ||= @session.post('facebook.events.get', {:uid => self.id}.merge(params)).map do |event|
64
+ Event.from_hash(event)
65
+ end
66
+ end
67
+
68
+ #
69
+ # Set the list of friends, given an array of User objects. If the list has been retrieved previously, will not set
70
+ def friends=(list_of_friends,flid=nil)
71
+ @friends_hash ||= {}
72
+ flid=cast_to_friend_list_id(flid)
73
+ #use __blank instead of nil so that this is cached
74
+ cache_key = flid||"__blank"
75
+
76
+ @friends_hash[cache_key] ||= list_of_friends
77
+ end
78
+
79
+ def cast_to_friend_list_id(flid)
80
+ case flid
81
+ when String
82
+ list=friend_lists.detect {|f| f.name==flid}
83
+ raise Facebooker::Session::InvalidFriendList unless list
84
+ list.flid
85
+ when FriendList
86
+ flid.flid
87
+ else
88
+ flid
89
+ end
90
+ end
91
+ ##
92
+ # Retrieve friends
93
+ def friends(flid = nil)
94
+ @friends_hash ||= {}
95
+ flid=cast_to_friend_list_id(flid)
96
+
97
+ #use __blank instead of nil so that this is cached
98
+ cache_key = flid||"__blank"
99
+ options = {:uid=>self.id}
100
+ options[:flid] = flid unless flid.nil?
101
+ @friends_hash[cache_key] ||= @session.post('facebook.friends.get', options,false).map do |uid|
102
+ User.new(uid, @session)
103
+ end
104
+ @friends_hash[cache_key]
105
+ end
106
+
107
+ def friend_lists
108
+ @friend_lists ||= @session.post('facebook.friends.getLists').map do |hash|
109
+ friend_list = FriendList.from_hash(hash)
110
+ friend_list.session = session
111
+ friend_list
112
+ end
113
+ end
114
+ ###
115
+ # Retrieve friends with user info populated
116
+ # Subsequent calls will be retrieved from memory.
117
+ # Optional: list of fields to retrieve as symbols
118
+ def friends!(*fields)
119
+ @friends ||= session.post('facebook.users.getInfo', :fields => collect(fields), :uids => friends.map{|f| f.id}.join(',')).map do |hash|
120
+ User.new(hash['uid'], session, hash)
121
+ end
122
+ end
123
+
124
+ ###
125
+ # Retrieve profile data for logged in user
126
+ # Optional: list of fields to retrieve as symbols
127
+ def populate(*fields)
128
+ session.post('facebook.users.getInfo', :fields => collect(fields), :uids => id) do |response|
129
+ populate_from_hash!(response.first)
130
+ end
131
+ end
132
+
133
+ def friends_with?(user_or_id)
134
+ friends.map{|f| f.to_i}.include?(user_or_id.to_i)
135
+ end
136
+
137
+ def friends_with_this_app
138
+ @friends_with_this_app ||= session.post('facebook.friends.getAppUsers').map do |uid|
139
+ User.new(uid, session)
140
+ end
141
+ end
142
+
143
+ def groups(gids = [])
144
+ args = gids.empty? ? {} : {:gids => gids}
145
+ @groups ||= session.post('facebook.groups.get', args).map do |hash|
146
+ group = Group.from_hash(hash)
147
+ group.session = session
148
+ group
149
+ end
150
+ end
151
+
152
+ def notifications
153
+ @notifications ||= Notifications.from_hash(session.post('facebook.notifications.get'))
154
+ end
155
+
156
+ def publish_story(story)
157
+ publish(story)
158
+ end
159
+
160
+ def publish_action(action)
161
+ publish(action)
162
+ end
163
+
164
+ def publish_templatized_action(action)
165
+ publish(action)
166
+ end
167
+
168
+ def albums
169
+ @albums ||= session.post('facebook.photos.getAlbums', :uid => self.id) do |response|
170
+ response.map do |hash|
171
+ Album.from_hash(hash)
172
+ end
173
+ end
174
+ end
175
+
176
+ def create_album(params)
177
+ @album = session.post('facebook.photos.createAlbum', params) {|response| Album.from_hash(response)}
178
+ end
179
+
180
+ def profile_photos
181
+ session.get_photos(nil, nil, profile_pic_album_id)
182
+ end
183
+
184
+ # Upload a photo to the user's profile.
185
+ #
186
+ # In your view, create a multipart form that posts directly to your application (not through canvas):
187
+ #
188
+ # <% form_tag photos_url(:canvas => false), :html => {:multipart => true, :promptpermission => 'photo_upload'} do %>
189
+ # Photo: <%= file_field_tag 'photo' %>
190
+ # Caption: <%= text_area_tag 'caption' %>
191
+ # <%= submit_tag 'Upload Photo', :class => 'inputsubmit' %>
192
+ # <% end %>
193
+ #
194
+ # And in your controller:
195
+ #
196
+ # class PhotosController < ApplicationController
197
+ # def create
198
+ # file = Net::HTTP::MultipartPostFile.new(
199
+ # params[:photo].original_filename,
200
+ # params[:photo].content_type,
201
+ # params[:photo].read
202
+ # )
203
+ #
204
+ # @photo = facebook_session.user.upload_photo(file, :caption => params[:caption])
205
+ # redirect_to photos_url(:canvas => true)
206
+ # end
207
+ # end
208
+ #
209
+ # Options correspond to http://wiki.developers.facebook.com/index.php/Photos.upload
210
+ def upload_photo(multipart_post_file, options = {})
211
+ Photo.from_hash(session.post_file('facebook.photos.upload',
212
+ options.merge(nil => multipart_post_file)))
213
+ end
214
+
215
+ # Upload a video to the user's profile.
216
+ #
217
+ # In your view, create a multipart form that posts directly to your application (not through canvas):
218
+ #
219
+ # <% form_tag videos_url(:canvas => false), :html => {:multipart => true, :promptpermission => 'video_upload'} do %>
220
+ # Video: <%= file_field_tag 'video' %>
221
+ # Title: <%= text_area_tag 'title' %>
222
+ # Description: <%= text_area_tag 'description' %>
223
+ # <%= submit_tag 'Upload Video', :class => 'inputsubmit' %>
224
+ # <% end %>
225
+ #
226
+ # And in your controller:
227
+ #
228
+ # class VideosController < ApplicationController
229
+ # def create
230
+ # file = Net::HTTP::MultipartPostFile.new(
231
+ # params[:photo].original_filename,
232
+ # params[:photo].content_type,
233
+ # params[:photo].read
234
+ # )
235
+ #
236
+ # @video = facebook_session.user.upload_video(file, :description => params[:description])
237
+ # redirect_to videos_url(:canvas => true)
238
+ # end
239
+ # end
240
+ #
241
+ # Options correspond to http://wiki.developers.facebook.com/index.php/Video.upload
242
+ def upload_video(multipart_post_file, options = {})
243
+ Video.from_hash(session.post_file('facebook.video.upload',
244
+ options.merge(nil => multipart_post_file, :base => Facebooker.video_server_base)))
245
+ end
246
+
247
+ def profile_fbml
248
+ session.post('facebook.profile.getFBML', :uid => id)
249
+ end
250
+
251
+ ##
252
+ # Set the profile FBML for this user
253
+ #
254
+ # This does not set profile actions, that should be done with profile_action=
255
+ def profile_fbml=(markup)
256
+ set_profile_fbml(markup, nil, nil, nil)
257
+ end
258
+
259
+ ##
260
+ # Set the mobile profile FBML
261
+ def mobile_fbml=(markup)
262
+ set_profile_fbml(nil, markup, nil,nil)
263
+ end
264
+
265
+ def profile_action=(markup)
266
+ set_profile_fbml(nil, nil, markup,nil)
267
+ end
268
+
269
+ def profile_main=(markup)
270
+ set_profile_fbml(nil,nil,nil,markup)
271
+ end
272
+
273
+ def set_profile_fbml(profile_fbml, mobile_fbml, profile_action_fbml, profile_main = nil)
274
+ parameters = {:uid => id}
275
+ parameters[:profile] = profile_fbml if profile_fbml
276
+ parameters[:profile_action] = profile_action_fbml if profile_action_fbml
277
+ parameters[:mobile_profile] = mobile_fbml if mobile_fbml
278
+ parameters[:profile_main] = profile_main if profile_main
279
+ session.post('facebook.profile.setFBML', parameters,false)
280
+ end
281
+
282
+ ## ** NEW PROFILE DESIGN ***
283
+ # Set a info section for this user
284
+ #
285
+ # Note: using set_profile_info as I feel using user.set_info could be confused with the user.getInfo facebook method.
286
+ # Also, I feel it fits in line with user.set_profile_fbml.
287
+ def set_profile_info(title, info_fields, format = :text)
288
+ session.post('facebook.profile.setInfo', :title => title, :uid => id,
289
+ :type => format.to_s == "text" ? 1 : 5, :info_fields => info_fields.to_json)
290
+ end
291
+
292
+ def get_profile_info
293
+ session.post('facebook.profile.getInfo', :uid => id)
294
+ end
295
+
296
+ ##
297
+ # This DOES NOT set the status of a user on Facebook
298
+ # Use the set_status method instead
299
+ def status=(message)
300
+ case message
301
+ when String,Status
302
+ @status = message
303
+ when Hash
304
+ @status = Status.from_hash(message)
305
+ end
306
+ end
307
+
308
+ ##
309
+ # Set the status for a user
310
+ # DOES NOT prepend "is" to the message
311
+ #
312
+ # requires extended permission.
313
+ def set_status(message)
314
+ self.status=message
315
+ session.post('facebook.users.setStatus',{:status=>message,:status_includes_verb=>1,:uid => uid}, false) do |ret|
316
+ ret
317
+ end
318
+ end
319
+
320
+ ##
321
+ # Checks to see if the user has enabled the given extended permission
322
+ def has_permission?(ext_perm) # ext_perm = email, offline_access, status_update, photo_upload, create_listing, create_event, rsvp_event, sms
323
+ session.post('facebook.users.hasAppPermission',:ext_perm=>ext_perm) == "1"
324
+ end
325
+
326
+ ##
327
+ # Convenience method to send email to the current user
328
+ def send_email(subject, text=nil, fbml=nil)
329
+ session.send_email([id], subject, text, fbml)
330
+ end
331
+
332
+ ##
333
+ # Convenience method to set cookie for the current user
334
+ def set_cookie(name, value, expires=nil, path=nil)
335
+ session.data.set_cookie(id, name, value, expires, path)
336
+ end
337
+
338
+ ##
339
+ # Convenience method to get cookies for the current user
340
+ def get_cookies(name=nil)
341
+ session.data.get_cookies(id, name)
342
+ end
343
+
344
+ ##
345
+ # Returns the user's id as an integer
346
+ def to_i
347
+ id
348
+ end
349
+
350
+ def to_s
351
+ id.to_s
352
+ end
353
+
354
+ ##
355
+ # Two Facebooker::User objects should be considered equal if their Facebook ids are equal
356
+ def ==(other_user)
357
+ other_user.is_a?(User) && id == other_user.id
358
+ end
359
+
360
+
361
+ # register a user with Facebook
362
+ # users should be a hast with at least an :email field
363
+ # you can optionally provide an :account_id field as well
364
+
365
+ def self.register(users)
366
+ user_map={}
367
+ users=users.map do |h|
368
+ returning h.dup do |d|
369
+ if email=d.delete(:email)
370
+ hash = hash_email(email)
371
+ user_map[hash]=h
372
+ d[:email_hash]=hash
373
+ end
374
+ end
375
+ end
376
+ Facebooker::Session.create.post("facebook.connect.registerUsers",:accounts=>users.to_json) do |ret|
377
+ ret.each do |hash|
378
+ user_map.delete(hash)
379
+ end
380
+ unless user_map.empty?
381
+ e=Facebooker::Session::UserRegistrationFailed.new
382
+ e.failed_users = user_map.values
383
+ raise e
384
+ end
385
+ ret
386
+ end
387
+ end
388
+
389
+ # Get a count of unconnected friends
390
+ def getUnconnectedFriendsCount
391
+ session.post("facebook.connect.getUnconnectedFriendsCount")
392
+ end
393
+
394
+
395
+ # Unregister an array of email hashes
396
+ def self.unregister(email_hashes)
397
+ Facebooker::Session.create.post("facebook.connect.unregisterUsers",:email_hashes=>email_hashes.to_json) do |ret|
398
+ ret.each do |hash|
399
+ email_hashes.delete(hash)
400
+ end
401
+ unless email_hashes.empty?
402
+ e=Facebooker::Session::UserUnRegistrationFailed.new
403
+ e.failed_users = email_hashes
404
+ raise e
405
+ end
406
+ ret
407
+ end
408
+ end
409
+
410
+ # unregister an array of email addresses
411
+ def self.unregister_emails(emails)
412
+ emails_hash = {}
413
+ emails.each {|e| emails_hash[hash_email(e)] = e}
414
+ begin
415
+ unregister(emails_hash.keys).collect {|r| emails_hash[r]}
416
+ rescue
417
+ # re-raise with emails instead of hashes.
418
+ e = Facebooker::Session::UserUnRegistrationFailed.new
419
+ e.failed_users = $!.failed_users.collect { |f| emails_hash[f] }
420
+ raise e
421
+ end
422
+ end
423
+
424
+ def self.hash_email(email)
425
+ email = email.downcase.strip
426
+ crc=Zlib.crc32(email)
427
+ md5=Digest::MD5.hexdigest(email)
428
+ "#{crc}_#{md5}"
429
+ end
430
+
431
+ def self.cast_to_facebook_id(object)
432
+ if object.respond_to?(:facebook_id)
433
+ object.facebook_id
434
+ else
435
+ object
436
+ end
437
+ end
438
+
439
+ def self.user_fields(fields = [])
440
+ valid_fields(fields)
441
+ end
442
+
443
+ def self.standard_fields(fields = [])
444
+ valid_fields(fields,STANDARD_FIELDS)
445
+ end
446
+
447
+ private
448
+ def publish(feed_story_or_action)
449
+ session.post(Facebooker::Feed::METHODS[feed_story_or_action.class.name.split(/::/).last], feed_story_or_action.to_params) == "1" ? true : false
450
+ end
451
+
452
+ def self.valid_fields(fields, allowable=FIELDS)
453
+ allowable.reject{|field_name| !fields.empty? && !fields.include?(field_name)}.join(',')
454
+ end
455
+
456
+ def collect(fields, allowable=FIELDS)
457
+ allowable.reject{|field_name| !fields.empty? && !fields.include?(field_name)}.join(',')
458
+ end
459
+
460
+ def profile_pic_album_id
461
+ merge_aid(-3, id)
462
+ end
463
+
464
+ def merge_aid(aid, uid)
465
+ (uid << 32) + (aid & 0xFFFFFFFF)
466
+ end
467
+
468
+ end
469
+ end
@@ -0,0 +1,9 @@
1
+ require 'facebooker/model'
2
+ module Facebooker
3
+ class Video
4
+ include Model
5
+ attr_accessor :vid, :owner, :title,
6
+ :link, :description, :created,
7
+ :story_fbid
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ module Facebooker
2
+ class WorkInfo
3
+ include Model
4
+ attr_accessor :end_date, :start_date, :company_name, :description, :position
5
+ attr_reader :location
6
+ def location=(location)
7
+ @location = location.kind_of?(Hash) ? Location.from_hash(location) : location
8
+ end
9
+ end
10
+ end