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.
- data/.autotest +15 -0
- data/CHANGELOG.rdoc +24 -0
- data/COPYING.rdoc +19 -0
- data/Manifest.txt +133 -0
- data/README.rdoc +104 -0
- data/Rakefile +85 -0
- data/TODO.rdoc +4 -0
- data/examples/desktop_login.rb +14 -0
- data/facebooker.gemspec +38 -0
- data/generators/facebook/facebook_generator.rb +14 -0
- data/generators/facebook/templates/config/facebooker.yml +49 -0
- data/generators/facebook/templates/public/javascripts/facebooker.js +83 -0
- data/generators/facebook_controller/USAGE +33 -0
- data/generators/facebook_controller/facebook_controller_generator.rb +40 -0
- data/generators/facebook_controller/templates/controller.rb +7 -0
- data/generators/facebook_controller/templates/functional_test.rb +11 -0
- data/generators/facebook_controller/templates/helper.rb +2 -0
- data/generators/facebook_controller/templates/view.fbml.erb +2 -0
- data/generators/facebook_controller/templates/view.html.erb +2 -0
- data/generators/facebook_publisher/facebook_publisher_generator.rb +14 -0
- data/generators/facebook_publisher/templates/create_facebook_templates.rb +15 -0
- data/generators/facebook_publisher/templates/publisher.rb +3 -0
- data/generators/facebook_scaffold/USAGE +27 -0
- data/generators/facebook_scaffold/facebook_scaffold_generator.rb +118 -0
- data/generators/facebook_scaffold/templates/controller.rb +93 -0
- data/generators/facebook_scaffold/templates/facebook_style.css +2579 -0
- data/generators/facebook_scaffold/templates/functional_test.rb +89 -0
- data/generators/facebook_scaffold/templates/helper.rb +2 -0
- data/generators/facebook_scaffold/templates/layout.fbml.erb +6 -0
- data/generators/facebook_scaffold/templates/layout.html.erb +17 -0
- data/generators/facebook_scaffold/templates/style.css +74 -0
- data/generators/facebook_scaffold/templates/view_edit.fbml.erb +13 -0
- data/generators/facebook_scaffold/templates/view_edit.html.erb +18 -0
- data/generators/facebook_scaffold/templates/view_index.fbml.erb +24 -0
- data/generators/facebook_scaffold/templates/view_index.html.erb +24 -0
- data/generators/facebook_scaffold/templates/view_new.fbml.erb +12 -0
- data/generators/facebook_scaffold/templates/view_new.html.erb +17 -0
- data/generators/facebook_scaffold/templates/view_show.fbml.erb +10 -0
- data/generators/facebook_scaffold/templates/view_show.html.erb +10 -0
- data/generators/publisher/publisher_generator.rb +14 -0
- data/generators/xd_receiver/templates/xd_receiver.html +10 -0
- data/generators/xd_receiver/xd_receiver_generator.rb +10 -0
- data/init.rb +25 -0
- data/install.rb +12 -0
- data/lib/facebooker/adapters/adapter_base.rb +91 -0
- data/lib/facebooker/adapters/bebo_adapter.rb +77 -0
- data/lib/facebooker/adapters/facebook_adapter.rb +52 -0
- data/lib/facebooker/admin.rb +42 -0
- data/lib/facebooker/batch_request.rb +45 -0
- data/lib/facebooker/data.rb +57 -0
- data/lib/facebooker/feed.rb +78 -0
- data/lib/facebooker/logging.rb +44 -0
- data/lib/facebooker/mobile.rb +20 -0
- data/lib/facebooker/mock/service.rb +50 -0
- data/lib/facebooker/mock/session.rb +18 -0
- data/lib/facebooker/model.rb +139 -0
- data/lib/facebooker/models/affiliation.rb +10 -0
- data/lib/facebooker/models/album.rb +11 -0
- data/lib/facebooker/models/applicationproperties.rb +39 -0
- data/lib/facebooker/models/applicationrestrictions.rb +10 -0
- data/lib/facebooker/models/cookie.rb +10 -0
- data/lib/facebooker/models/education_info.rb +11 -0
- data/lib/facebooker/models/event.rb +28 -0
- data/lib/facebooker/models/friend_list.rb +16 -0
- data/lib/facebooker/models/group.rb +36 -0
- data/lib/facebooker/models/info_item.rb +10 -0
- data/lib/facebooker/models/info_section.rb +10 -0
- data/lib/facebooker/models/location.rb +8 -0
- data/lib/facebooker/models/notifications.rb +17 -0
- data/lib/facebooker/models/page.rb +28 -0
- data/lib/facebooker/models/photo.rb +19 -0
- data/lib/facebooker/models/tag.rb +12 -0
- data/lib/facebooker/models/user.rb +497 -0
- data/lib/facebooker/models/video.rb +9 -0
- data/lib/facebooker/models/work_info.rb +10 -0
- data/lib/facebooker/parser.rb +650 -0
- data/lib/facebooker/rails/backwards_compatible_param_checks.rb +31 -0
- data/lib/facebooker/rails/controller.rb +337 -0
- data/lib/facebooker/rails/cucumber/world.rb +46 -0
- data/lib/facebooker/rails/cucumber.rb +28 -0
- data/lib/facebooker/rails/extensions/action_controller.rb +48 -0
- data/lib/facebooker/rails/extensions/rack_setup.rb +6 -0
- data/lib/facebooker/rails/extensions/routing.rb +15 -0
- data/lib/facebooker/rails/facebook_form_builder.rb +112 -0
- data/lib/facebooker/rails/facebook_pretty_errors.rb +22 -0
- data/lib/facebooker/rails/facebook_request_fix.rb +30 -0
- data/lib/facebooker/rails/facebook_request_fix_2-3.rb +31 -0
- data/lib/facebooker/rails/facebook_session_handling.rb +68 -0
- data/lib/facebooker/rails/facebook_url_helper.rb +192 -0
- data/lib/facebooker/rails/facebook_url_rewriting.rb +60 -0
- data/lib/facebooker/rails/helpers/fb_connect.rb +118 -0
- data/lib/facebooker/rails/helpers.rb +780 -0
- data/lib/facebooker/rails/integration_session.rb +38 -0
- data/lib/facebooker/rails/profile_publisher_extensions.rb +42 -0
- data/lib/facebooker/rails/publisher.rb +554 -0
- data/lib/facebooker/rails/routing.rb +49 -0
- data/lib/facebooker/rails/test_helpers.rb +68 -0
- data/lib/facebooker/rails/utilities.rb +22 -0
- data/lib/facebooker/server_cache.rb +24 -0
- data/lib/facebooker/service.rb +102 -0
- data/lib/facebooker/session.rb +606 -0
- data/lib/facebooker/version.rb +9 -0
- data/lib/facebooker.rb +180 -0
- data/lib/net/http_multipart_post.rb +123 -0
- data/lib/rack/facebook.rb +77 -0
- data/lib/tasks/facebooker.rake +18 -0
- data/lib/tasks/tunnel.rake +46 -0
- data/rails/init.rb +1 -0
- data/setup.rb +1585 -0
- data/templates/layout.erb +24 -0
- data/test/facebooker/adapters_test.rb +96 -0
- data/test/facebooker/admin_test.rb +102 -0
- data/test/facebooker/batch_request_test.rb +83 -0
- data/test/facebooker/data_test.rb +86 -0
- data/test/facebooker/logging_test.rb +43 -0
- data/test/facebooker/mobile_test.rb +45 -0
- data/test/facebooker/model_test.rb +133 -0
- data/test/facebooker/models/event_test.rb +15 -0
- data/test/facebooker/models/photo_test.rb +16 -0
- data/test/facebooker/models/user_test.rb +343 -0
- data/test/facebooker/rails/facebook_request_fix_2-3_test.rb +24 -0
- data/test/facebooker/rails/facebook_url_rewriting_test.rb +39 -0
- data/test/facebooker/rails/publisher_test.rb +481 -0
- data/test/facebooker/rails_integration_test.rb +1398 -0
- data/test/facebooker/server_cache_test.rb +44 -0
- data/test/facebooker/session_test.rb +614 -0
- data/test/facebooker_test.rb +951 -0
- data/test/fixtures/multipart_post_body_with_only_parameters.txt +33 -0
- data/test/fixtures/multipart_post_body_with_single_file.txt +38 -0
- data/test/fixtures/multipart_post_body_with_single_file_that_has_nil_key.txt +38 -0
- data/test/net/http_multipart_post_test.rb +52 -0
- data/test/rack/facebook_test.rb +61 -0
- data/test/rails_test_helper.rb +27 -0
- data/test/test_helper.rb +74 -0
- metadata +232 -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,:pic_large,:type,:website,:has_added_app,:founded,:company_overview,:mission,:products,:location,:parking,:public_transit,:hours,:attire,:payment_options,:culinary_team,:general_manager,:price_range,:restaurant_services,:restaurant_specialties,:release_date,:genre,:starring,:screenplay_by,:directed_by,:produced_by,:studio,:awards,:plot_outline,:network,:season,:schedule,:written_by,:band_members,:hometown,:current_location,:record_label,:booking_agent,:artists_we_like,:influences,:band_interests,:bio,:affiliation,:birthday,:personal_info,:personal_interests,:members,:built,:features,:mpg,:general_info,:fan_count
|
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,497 @@
|
|
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 = [:status, :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
|
+
###
|
108
|
+
# Publish a post into the stream on the user's Wall and News Feed. This
|
109
|
+
# post also appears in the user's friend's streams. The +publish_stream+
|
110
|
+
# extended permission must be granted in order to use this method.
|
111
|
+
#
|
112
|
+
# See: http://wiki.developers.facebook.com/index.php/Stream.publish
|
113
|
+
#
|
114
|
+
# +target+ can be the current user or some other user.
|
115
|
+
#
|
116
|
+
# Example:
|
117
|
+
# # Publish a message to my own wall:
|
118
|
+
# me.publish_to(me, :message => 'hello world')
|
119
|
+
#
|
120
|
+
# # Publish to a friend's wall with an action link:
|
121
|
+
# me.publish_to(my_friend, :message => 'how are you?', :action_links => [
|
122
|
+
# :text => 'my website',
|
123
|
+
# :href => 'http://tenderlovemaking.com/'
|
124
|
+
# ])
|
125
|
+
def publish_to target, options = {}
|
126
|
+
@session.post('facebook.stream.publish',
|
127
|
+
:uid => self.id,
|
128
|
+
:target_id => target.id,
|
129
|
+
:message => options[:message],
|
130
|
+
:attachment => options[:attachment],
|
131
|
+
:action_links => options[:action_links]
|
132
|
+
)
|
133
|
+
end
|
134
|
+
|
135
|
+
def friend_lists
|
136
|
+
@friend_lists ||= @session.post('facebook.friends.getLists').map do |hash|
|
137
|
+
friend_list = FriendList.from_hash(hash)
|
138
|
+
friend_list.session = session
|
139
|
+
friend_list
|
140
|
+
end
|
141
|
+
end
|
142
|
+
###
|
143
|
+
# Retrieve friends with user info populated
|
144
|
+
# Subsequent calls will be retrieved from memory.
|
145
|
+
# Optional: list of fields to retrieve as symbols
|
146
|
+
def friends!(*fields)
|
147
|
+
@friends ||= session.post('facebook.users.getInfo', :fields => collect(fields), :uids => friends.map{|f| f.id}.join(',')).map do |hash|
|
148
|
+
User.new(hash['uid'], session, hash)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
###
|
153
|
+
# Retrieve profile data for logged in user
|
154
|
+
# Optional: list of fields to retrieve as symbols
|
155
|
+
def populate(*fields)
|
156
|
+
session.post('facebook.users.getInfo', :fields => collect(fields), :uids => id) do |response|
|
157
|
+
populate_from_hash!(response.first)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def friends_with?(user_or_id)
|
162
|
+
friends.map{|f| f.to_i}.include?(user_or_id.to_i)
|
163
|
+
end
|
164
|
+
|
165
|
+
def friends_with_this_app
|
166
|
+
@friends_with_this_app ||= session.post('facebook.friends.getAppUsers').map do |uid|
|
167
|
+
User.new(uid, session)
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
def groups(gids = [])
|
172
|
+
args = gids.empty? ? {} : {:gids => gids}
|
173
|
+
@groups ||= session.post('facebook.groups.get', args).map do |hash|
|
174
|
+
group = Group.from_hash(hash)
|
175
|
+
group.session = session
|
176
|
+
group
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
def notifications
|
181
|
+
@notifications ||= Notifications.from_hash(session.post('facebook.notifications.get'))
|
182
|
+
end
|
183
|
+
|
184
|
+
def publish_story(story)
|
185
|
+
publish(story)
|
186
|
+
end
|
187
|
+
|
188
|
+
def publish_action(action)
|
189
|
+
publish(action)
|
190
|
+
end
|
191
|
+
|
192
|
+
def publish_templatized_action(action)
|
193
|
+
publish(action)
|
194
|
+
end
|
195
|
+
|
196
|
+
def albums
|
197
|
+
@albums ||= session.post('facebook.photos.getAlbums', :uid => self.id) do |response|
|
198
|
+
response.map do |hash|
|
199
|
+
Album.from_hash(hash)
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
def create_album(params)
|
205
|
+
@album = session.post('facebook.photos.createAlbum', params) {|response| Album.from_hash(response)}
|
206
|
+
end
|
207
|
+
|
208
|
+
def profile_photos
|
209
|
+
session.get_photos(nil, nil, profile_pic_album_id)
|
210
|
+
end
|
211
|
+
|
212
|
+
# Upload a photo to the user's profile.
|
213
|
+
#
|
214
|
+
# In your view, create a multipart form that posts directly to your application (not through canvas):
|
215
|
+
#
|
216
|
+
# <% form_tag photos_url(:canvas => false), :html => {:multipart => true, :promptpermission => 'photo_upload'} do %>
|
217
|
+
# Photo: <%= file_field_tag 'photo' %>
|
218
|
+
# Caption: <%= text_area_tag 'caption' %>
|
219
|
+
# <%= submit_tag 'Upload Photo', :class => 'inputsubmit' %>
|
220
|
+
# <% end %>
|
221
|
+
#
|
222
|
+
# And in your controller:
|
223
|
+
#
|
224
|
+
# class PhotosController < ApplicationController
|
225
|
+
# def create
|
226
|
+
# file = Net::HTTP::MultipartPostFile.new(
|
227
|
+
# params[:photo].original_filename,
|
228
|
+
# params[:photo].content_type,
|
229
|
+
# params[:photo].read
|
230
|
+
# )
|
231
|
+
#
|
232
|
+
# @photo = facebook_session.user.upload_photo(file, :caption => params[:caption])
|
233
|
+
# redirect_to photos_url(:canvas => true)
|
234
|
+
# end
|
235
|
+
# end
|
236
|
+
#
|
237
|
+
# Options correspond to http://wiki.developers.facebook.com/index.php/Photos.upload
|
238
|
+
def upload_photo(multipart_post_file, options = {})
|
239
|
+
Photo.from_hash(session.post_file('facebook.photos.upload',
|
240
|
+
options.merge(nil => multipart_post_file)))
|
241
|
+
end
|
242
|
+
|
243
|
+
# Upload a video to the user's profile.
|
244
|
+
#
|
245
|
+
# In your view, create a multipart form that posts directly to your application (not through canvas):
|
246
|
+
#
|
247
|
+
# <% form_tag videos_url(:canvas => false), :html => {:multipart => true, :promptpermission => 'video_upload'} do %>
|
248
|
+
# Video: <%= file_field_tag 'video' %>
|
249
|
+
# Title: <%= text_area_tag 'title' %>
|
250
|
+
# Description: <%= text_area_tag 'description' %>
|
251
|
+
# <%= submit_tag 'Upload Video', :class => 'inputsubmit' %>
|
252
|
+
# <% end %>
|
253
|
+
#
|
254
|
+
# And in your controller:
|
255
|
+
#
|
256
|
+
# class VideosController < ApplicationController
|
257
|
+
# def create
|
258
|
+
# file = Net::HTTP::MultipartPostFile.new(
|
259
|
+
# params[:photo].original_filename,
|
260
|
+
# params[:photo].content_type,
|
261
|
+
# params[:photo].read
|
262
|
+
# )
|
263
|
+
#
|
264
|
+
# @video = facebook_session.user.upload_video(file, :description => params[:description])
|
265
|
+
# redirect_to videos_url(:canvas => true)
|
266
|
+
# end
|
267
|
+
# end
|
268
|
+
#
|
269
|
+
# Options correspond to http://wiki.developers.facebook.com/index.php/Video.upload
|
270
|
+
def upload_video(multipart_post_file, options = {})
|
271
|
+
Video.from_hash(session.post_file('facebook.video.upload',
|
272
|
+
options.merge(nil => multipart_post_file, :base => Facebooker.video_server_base)))
|
273
|
+
end
|
274
|
+
|
275
|
+
def profile_fbml
|
276
|
+
session.post('facebook.profile.getFBML', :uid => id)
|
277
|
+
end
|
278
|
+
|
279
|
+
##
|
280
|
+
# Set the profile FBML for this user
|
281
|
+
#
|
282
|
+
# This does not set profile actions, that should be done with profile_action=
|
283
|
+
def profile_fbml=(markup)
|
284
|
+
set_profile_fbml(markup, nil, nil, nil)
|
285
|
+
end
|
286
|
+
|
287
|
+
##
|
288
|
+
# Set the mobile profile FBML
|
289
|
+
def mobile_fbml=(markup)
|
290
|
+
set_profile_fbml(nil, markup, nil,nil)
|
291
|
+
end
|
292
|
+
|
293
|
+
def profile_action=(markup)
|
294
|
+
set_profile_fbml(nil, nil, markup,nil)
|
295
|
+
end
|
296
|
+
|
297
|
+
def profile_main=(markup)
|
298
|
+
set_profile_fbml(nil,nil,nil,markup)
|
299
|
+
end
|
300
|
+
|
301
|
+
def set_profile_fbml(profile_fbml, mobile_fbml, profile_action_fbml, profile_main = nil)
|
302
|
+
parameters = {:uid => id}
|
303
|
+
parameters[:profile] = profile_fbml if profile_fbml
|
304
|
+
parameters[:profile_action] = profile_action_fbml if profile_action_fbml
|
305
|
+
parameters[:mobile_profile] = mobile_fbml if mobile_fbml
|
306
|
+
parameters[:profile_main] = profile_main if profile_main
|
307
|
+
session.post('facebook.profile.setFBML', parameters,false)
|
308
|
+
end
|
309
|
+
|
310
|
+
## ** NEW PROFILE DESIGN ***
|
311
|
+
# Set a info section for this user
|
312
|
+
#
|
313
|
+
# Note: using set_profile_info as I feel using user.set_info could be confused with the user.getInfo facebook method.
|
314
|
+
# Also, I feel it fits in line with user.set_profile_fbml.
|
315
|
+
def set_profile_info(title, info_fields, format = :text)
|
316
|
+
session.post('facebook.profile.setInfo', :title => title, :uid => id,
|
317
|
+
:type => format.to_s == "text" ? 1 : 5, :info_fields => info_fields.to_json)
|
318
|
+
end
|
319
|
+
|
320
|
+
def get_profile_info
|
321
|
+
session.post('facebook.profile.getInfo', :uid => id)
|
322
|
+
end
|
323
|
+
|
324
|
+
##
|
325
|
+
# This DOES NOT set the status of a user on Facebook
|
326
|
+
# Use the set_status method instead
|
327
|
+
def status=(message)
|
328
|
+
case message
|
329
|
+
when String,Status
|
330
|
+
@status = message
|
331
|
+
when Hash
|
332
|
+
@status = Status.from_hash(message)
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
336
|
+
##
|
337
|
+
# Set the status for a user
|
338
|
+
# DOES NOT prepend "is" to the message
|
339
|
+
#
|
340
|
+
# requires extended permission.
|
341
|
+
def set_status(message)
|
342
|
+
self.status=message
|
343
|
+
session.post('facebook.users.setStatus',{:status=>message,:status_includes_verb=>1,:uid => uid}, false) do |ret|
|
344
|
+
ret
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
348
|
+
##
|
349
|
+
# Checks to see if the user has enabled the given extended permission
|
350
|
+
def has_permission?(ext_perm) # ext_perm = email, offline_access, status_update, photo_upload, create_listing, create_event, rsvp_event, sms
|
351
|
+
session.post('facebook.users.hasAppPermission',:ext_perm=>ext_perm) == "1"
|
352
|
+
end
|
353
|
+
|
354
|
+
##
|
355
|
+
# Convenience method to send email to the current user
|
356
|
+
def send_email(subject, text=nil, fbml=nil)
|
357
|
+
session.send_email([id], subject, text, fbml)
|
358
|
+
end
|
359
|
+
|
360
|
+
##
|
361
|
+
# Convenience method to set cookie for the current user
|
362
|
+
def set_cookie(name, value, expires=nil, path=nil)
|
363
|
+
session.data.set_cookie(id, name, value, expires, path)
|
364
|
+
end
|
365
|
+
|
366
|
+
##
|
367
|
+
# Convenience method to get cookies for the current user
|
368
|
+
def get_cookies(name=nil)
|
369
|
+
session.data.get_cookies(id, name)
|
370
|
+
end
|
371
|
+
|
372
|
+
##
|
373
|
+
# Returns the user's id as an integer
|
374
|
+
def to_i
|
375
|
+
id
|
376
|
+
end
|
377
|
+
|
378
|
+
def to_s
|
379
|
+
id.to_s
|
380
|
+
end
|
381
|
+
|
382
|
+
##
|
383
|
+
# Two Facebooker::User objects should be considered equal if their Facebook ids are equal
|
384
|
+
def ==(other_user)
|
385
|
+
other_user.is_a?(User) && id == other_user.id
|
386
|
+
end
|
387
|
+
|
388
|
+
|
389
|
+
# register a user with Facebook
|
390
|
+
# users should be a hast with at least an :email field
|
391
|
+
# you can optionally provide an :account_id field as well
|
392
|
+
|
393
|
+
def self.register(users)
|
394
|
+
user_map={}
|
395
|
+
users=users.map do |h|
|
396
|
+
returning h.dup do |d|
|
397
|
+
if email=d.delete(:email)
|
398
|
+
hash = hash_email(email)
|
399
|
+
user_map[hash]=h
|
400
|
+
d[:email_hash]=hash
|
401
|
+
end
|
402
|
+
end
|
403
|
+
end
|
404
|
+
Facebooker::Session.create.post("facebook.connect.registerUsers",:accounts=>users.to_json) do |ret|
|
405
|
+
ret.each do |hash|
|
406
|
+
user_map.delete(hash)
|
407
|
+
end
|
408
|
+
unless user_map.empty?
|
409
|
+
e=Facebooker::Session::UserRegistrationFailed.new
|
410
|
+
e.failed_users = user_map.values
|
411
|
+
raise e
|
412
|
+
end
|
413
|
+
ret
|
414
|
+
end
|
415
|
+
end
|
416
|
+
|
417
|
+
# Get a count of unconnected friends
|
418
|
+
def getUnconnectedFriendsCount
|
419
|
+
session.post("facebook.connect.getUnconnectedFriendsCount")
|
420
|
+
end
|
421
|
+
|
422
|
+
|
423
|
+
# Unregister an array of email hashes
|
424
|
+
def self.unregister(email_hashes)
|
425
|
+
Facebooker::Session.create.post("facebook.connect.unregisterUsers",:email_hashes=>email_hashes.to_json) do |ret|
|
426
|
+
ret.each do |hash|
|
427
|
+
email_hashes.delete(hash)
|
428
|
+
end
|
429
|
+
unless email_hashes.empty?
|
430
|
+
e=Facebooker::Session::UserUnRegistrationFailed.new
|
431
|
+
e.failed_users = email_hashes
|
432
|
+
raise e
|
433
|
+
end
|
434
|
+
ret
|
435
|
+
end
|
436
|
+
end
|
437
|
+
|
438
|
+
# unregister an array of email addresses
|
439
|
+
def self.unregister_emails(emails)
|
440
|
+
emails_hash = {}
|
441
|
+
emails.each {|e| emails_hash[hash_email(e)] = e}
|
442
|
+
begin
|
443
|
+
unregister(emails_hash.keys).collect {|r| emails_hash[r]}
|
444
|
+
rescue
|
445
|
+
# re-raise with emails instead of hashes.
|
446
|
+
e = Facebooker::Session::UserUnRegistrationFailed.new
|
447
|
+
e.failed_users = $!.failed_users.collect { |f| emails_hash[f] }
|
448
|
+
raise e
|
449
|
+
end
|
450
|
+
end
|
451
|
+
|
452
|
+
def self.hash_email(email)
|
453
|
+
email = email.downcase.strip
|
454
|
+
crc=Zlib.crc32(email)
|
455
|
+
md5=Digest::MD5.hexdigest(email)
|
456
|
+
"#{crc}_#{md5}"
|
457
|
+
end
|
458
|
+
|
459
|
+
def self.cast_to_facebook_id(object)
|
460
|
+
if object.respond_to?(:facebook_id)
|
461
|
+
object.facebook_id
|
462
|
+
else
|
463
|
+
object
|
464
|
+
end
|
465
|
+
end
|
466
|
+
|
467
|
+
def self.user_fields(fields = [])
|
468
|
+
valid_fields(fields)
|
469
|
+
end
|
470
|
+
|
471
|
+
def self.standard_fields(fields = [])
|
472
|
+
valid_fields(fields,STANDARD_FIELDS)
|
473
|
+
end
|
474
|
+
|
475
|
+
private
|
476
|
+
def publish(feed_story_or_action)
|
477
|
+
session.post(Facebooker::Feed::METHODS[feed_story_or_action.class.name.split(/::/).last], feed_story_or_action.to_params) == "1" ? true : false
|
478
|
+
end
|
479
|
+
|
480
|
+
def self.valid_fields(fields, allowable=FIELDS)
|
481
|
+
allowable.reject{|field_name| !fields.empty? && !fields.include?(field_name)}.join(',')
|
482
|
+
end
|
483
|
+
|
484
|
+
def collect(fields, allowable=FIELDS)
|
485
|
+
allowable.reject{|field_name| !fields.empty? && !fields.include?(field_name)}.join(',')
|
486
|
+
end
|
487
|
+
|
488
|
+
def profile_pic_album_id
|
489
|
+
merge_aid(-3, id)
|
490
|
+
end
|
491
|
+
|
492
|
+
def merge_aid(aid, uid)
|
493
|
+
(uid << 32) + (aid & 0xFFFFFFFF)
|
494
|
+
end
|
495
|
+
|
496
|
+
end
|
497
|
+
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
|