facebooker-lite 1.0.67
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 +114 -0
- data/README.rdoc +120 -0
- data/Rakefile +94 -0
- data/TODO.rdoc +4 -0
- data/facebooker.gemspec +42 -0
- data/generators/xd_receiver/templates/xd_receiver.html +10 -0
- data/generators/xd_receiver/templates/xd_receiver_ssl.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.rb +261 -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 +60 -0
- data/lib/facebooker/admin.rb +42 -0
- data/lib/facebooker/application.rb +37 -0
- data/lib/facebooker/attachment.rb +51 -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/comment.rb +9 -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/family_relative_info.rb +7 -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/message_thread.rb +89 -0
- data/lib/facebooker/models/notifications.rb +17 -0
- data/lib/facebooker/models/page.rb +46 -0
- data/lib/facebooker/models/photo.rb +19 -0
- data/lib/facebooker/models/tag.rb +12 -0
- data/lib/facebooker/models/user.rb +751 -0
- data/lib/facebooker/models/video.rb +9 -0
- data/lib/facebooker/models/work_info.rb +10 -0
- data/lib/facebooker/parser.rb +970 -0
- data/lib/facebooker/rails/backwards_compatible_param_checks.rb +31 -0
- data/lib/facebooker/rails/controller.rb +353 -0
- data/lib/facebooker/rails/extensions/action_controller.rb +47 -0
- data/lib/facebooker/rails/extensions/rack_setup.rb +16 -0
- data/lib/facebooker/rails/extensions/routing.rb +15 -0
- data/lib/facebooker/rails/facebook_pretty_errors.rb +22 -0
- data/lib/facebooker/rails/facebook_request_fix.rb +28 -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_rewriting.rb +60 -0
- data/lib/facebooker/rails/helpers/fb_connect.rb +75 -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 +608 -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 +103 -0
- data/lib/facebooker/service/base_service.rb +19 -0
- data/lib/facebooker/service/curl_service.rb +44 -0
- data/lib/facebooker/service/net_http_service.rb +12 -0
- data/lib/facebooker/service/typhoeus_multi_service.rb +27 -0
- data/lib/facebooker/service/typhoeus_service.rb +17 -0
- data/lib/facebooker/session.rb +786 -0
- data/lib/facebooker/stream_post.rb +19 -0
- data/lib/facebooker/version.rb +9 -0
- data/lib/net/http_multipart_post.rb +123 -0
- data/lib/rack/facebook.rb +89 -0
- data/lib/rack/facebook_session.rb +21 -0
- data/lib/tasks/facebooker.rake +19 -0
- data/lib/tasks/facebooker.rb +2 -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 +191 -0
- data/test/facebooker/admin_test.rb +102 -0
- data/test/facebooker/application_test.rb +110 -0
- data/test/facebooker/attachment_test.rb +72 -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/page_test.rb +56 -0
- data/test/facebooker/models/photo_test.rb +16 -0
- data/test/facebooker/models/user_test.rb +1074 -0
- data/test/facebooker/rails/facebook_request_fix_2-3_test.rb +25 -0
- data/test/facebooker/rails/facebook_url_rewriting_test.rb +76 -0
- data/test/facebooker/rails/integration_session_test.rb +13 -0
- data/test/facebooker/rails/publisher_test.rb +538 -0
- data/test/facebooker/rails_integration_test.rb +1543 -0
- data/test/facebooker/server_cache_test.rb +44 -0
- data/test/facebooker/service_test.rb +58 -0
- data/test/facebooker/session_test.rb +883 -0
- data/test/facebooker_test.rb +1263 -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_session_test.rb +34 -0
- data/test/rack/facebook_test.rb +73 -0
- data/test/rails_test_helper.rb +36 -0
- data/test/test_helper.rb +74 -0
- metadata +278 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
module Facebooker
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class FacebookAdapter < AdapterBase
|
|
5
|
+
|
|
6
|
+
def canvas_server_base
|
|
7
|
+
"apps.facebook.com"
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def api_server_base
|
|
11
|
+
"api.facebook.com"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def video_server_base
|
|
15
|
+
"api-video.facebook.com"
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def www_server_base_url
|
|
19
|
+
"www.facebook.com"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def api_rest_path
|
|
23
|
+
"/restserver.php"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def api_key
|
|
27
|
+
ENV['FACEBOOK_API_KEY'] || super
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def secret_key
|
|
31
|
+
ENV['FACEBOOK_SECRET_KEY'] || super
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def is_for?(application_context)
|
|
35
|
+
application_context == :facebook
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def login_url_base
|
|
41
|
+
"http://#{www_server_base_url}/login.php?api_key=#{api_key}&v=1.0"
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def install_url_base
|
|
45
|
+
"http://#{www_server_base_url}/install.php?api_key=#{api_key}&v=1.0"
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def connect_permission_url_base
|
|
49
|
+
"http://#{www_server_base_url}/connect/prompt_permissions.php?api_key=#{api_key}&v=1.0"
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def permission_url_base
|
|
53
|
+
"http://#{www_server_base_url}/authorize.php?api_key=#{api_key}&v=1.0"
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
module Facebooker
|
|
2
|
+
class Admin
|
|
3
|
+
def initialize(session)
|
|
4
|
+
@session = session
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
# ** BETA ***
|
|
8
|
+
# +properties+: Hash of properties you want to set
|
|
9
|
+
def set_app_properties(properties)
|
|
10
|
+
properties = properties.respond_to?(:to_json) ? properties.to_json : properties
|
|
11
|
+
(@session.post 'facebook.admin.setAppProperties', :properties => properties) == '1'
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# ** BETA ***
|
|
15
|
+
# +properties+: Hash of properties you want to view.
|
|
16
|
+
def get_app_properties(*properties)
|
|
17
|
+
json = @session.post('facebook.admin.getAppProperties', :properties => properties.to_json)
|
|
18
|
+
hash = Facebooker.json_decode(CGI.unescapeHTML(json))
|
|
19
|
+
@properties = ApplicationProperties.from_hash(hash)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# ** BETA ***
|
|
23
|
+
# +restrictions+: Hash of restrictions you want to set.
|
|
24
|
+
def set_restriction_info(restrictions)
|
|
25
|
+
restrictions = restrictions.respond_to?(:to_json) ? restrictions.to_json : restrictions
|
|
26
|
+
(@session.post 'facebook.admin.setRestrictionInfo', :restriction_str => restrictions) == '1'
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# ** BETA ***
|
|
30
|
+
def get_restriction_info(*restrictions)
|
|
31
|
+
json = @session.post('facebook.admin.getRestrictionInfo')
|
|
32
|
+
hash = Facebooker.json_decode(CGI.unescapeHTML(json))
|
|
33
|
+
@restrictions = ApplicationRestrictions.from_hash(hash)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Integration points include..
|
|
37
|
+
# :notifications_per_day, :requests_per_day, :emails_per_day, :email_disable_message_location
|
|
38
|
+
def get_allocation(integration_point)
|
|
39
|
+
@session.post('facebook.admin.getAllocation', :integration_point_name => integration_point.to_s).to_i
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
module Facebooker
|
|
2
|
+
class Application
|
|
3
|
+
def initialize(session)
|
|
4
|
+
@session = session
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
# +properties+: Hash of properties of the desired application. Specify exactly one of: application_id, application_api_key or application_canvas_name
|
|
8
|
+
# eg: application.get_public_info(:application_canvas_name => ENV['FACEBOOKER_RELATIVE_URL_ROOT'])
|
|
9
|
+
def get_public_info(properties)
|
|
10
|
+
(@session.post 'facebook.application.getPublicInfo', properties)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# facebook_session.application.add_global_news [{ :message => 'Hi all users', :action_link => { :text => "Hi application", :href => 'http://facebook.er/' }}], 'http://facebook.er/icon.png'
|
|
14
|
+
def add_global_news(news, image=nil)
|
|
15
|
+
params = {}
|
|
16
|
+
params[:news] = news
|
|
17
|
+
params[:image] = image if image
|
|
18
|
+
@session.post('facebook.dashboard.addGlobalNews', params)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# currently bugged on Facebook; returns all
|
|
22
|
+
# facebook_session.application.get_global_news '310354202543'
|
|
23
|
+
def get_global_news(*news_ids)
|
|
24
|
+
params = {}
|
|
25
|
+
params[:news_ids] = news_ids.flatten if news_ids
|
|
26
|
+
@session.post('facebook.dashboard.getGlobalNews', params)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# facebook_session.application.clear_global_news '310354202543'
|
|
30
|
+
def clear_global_news(*news_ids)
|
|
31
|
+
params = {}
|
|
32
|
+
params[:news_ids] = news_ids.flatten if news_ids
|
|
33
|
+
@session.post('facebook.dashboard.clearGlobalNews', params)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
class Facebooker::Attachment
|
|
2
|
+
|
|
3
|
+
def initialize
|
|
4
|
+
@storage = {}
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def self.hash_populating_accessor(*names)
|
|
8
|
+
names.each do |name|
|
|
9
|
+
define_method(name) do
|
|
10
|
+
@storage[name]
|
|
11
|
+
end
|
|
12
|
+
define_method("#{name}=") do |val|
|
|
13
|
+
@storage[name]=val
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
hash_populating_accessor :name,:href, :comments_xid, :description, :caption
|
|
19
|
+
|
|
20
|
+
def add_media(hash)
|
|
21
|
+
@storage[:media]||=[]
|
|
22
|
+
@storage[:media] << hash
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def add_image(source,href)
|
|
26
|
+
add_media({:type=>"image",:src=>source,:href=>href})
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def add_mp3(source,title=nil,artist=nil,album=nil)
|
|
30
|
+
params = {:src=>source,:type=>"mp3"}
|
|
31
|
+
params[:title] = title unless title.nil?
|
|
32
|
+
params[:artist] = artist unless artist.nil?
|
|
33
|
+
params[:album] = album unless album.nil?
|
|
34
|
+
add_media(params)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def add_flash(swfsource, imgsource, width=nil, height=nil, expanded_width=nil, expanded_height=nil)
|
|
38
|
+
params={:type=>"flash",:swfsrc=>swfsource,:imgsrc=>imgsource}
|
|
39
|
+
params[:width] = width unless width.nil?
|
|
40
|
+
params[:height] = height unless height.nil?
|
|
41
|
+
params[:expanded_width] = expanded_width unless expanded_width.nil?
|
|
42
|
+
params[:expanded_height] = expanded_height unless expanded_height.nil?
|
|
43
|
+
add_media(params)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def to_hash
|
|
47
|
+
@storage
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
module Facebooker
|
|
2
|
+
class BatchRequest
|
|
3
|
+
instance_methods.each { |m| undef_method m unless m =~ /(^__|^nil\?$|^send$|proxy_|^respond_to\?$|^new|object_id$)/ }
|
|
4
|
+
attr_reader :uri
|
|
5
|
+
attr_reader :method
|
|
6
|
+
class UnexecutedRequest < StandardError; end
|
|
7
|
+
def initialize(params,proc)
|
|
8
|
+
@exception = nil
|
|
9
|
+
@result = nil
|
|
10
|
+
@method = params[:method]
|
|
11
|
+
@uri = params.map{|k,v| "#{k}=#{CGI.escape(v.to_s)}"}.join("&")
|
|
12
|
+
@proc = proc
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def result=(result_object)
|
|
16
|
+
@result = @proc.nil? ? result_object : @proc.call(result_object)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def exception_raised=(ex)
|
|
20
|
+
@exception=ex
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def exception_raised?
|
|
24
|
+
@exception.nil? ? false : raise(@exception)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def respond_to?(name)
|
|
28
|
+
super || @result.respond_to?(name)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def ===(other)
|
|
32
|
+
other === @result
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def method_missing(name,*args,&proc)
|
|
36
|
+
if @exception
|
|
37
|
+
raise @exception
|
|
38
|
+
elsif @result.nil?
|
|
39
|
+
raise UnexecutedRequest.new("You must execute the batch before accessing the result: #{@uri}")
|
|
40
|
+
else
|
|
41
|
+
@result.send(name,*args,&proc)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
module Facebooker
|
|
2
|
+
class Data
|
|
3
|
+
def initialize(session)
|
|
4
|
+
@session = session
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
##
|
|
8
|
+
# ** BETA ***
|
|
9
|
+
# Sets a cookie on Facebook
|
|
10
|
+
# +user+ The user for whom this cookie needs to be set.
|
|
11
|
+
# +name+ Name of the cookie
|
|
12
|
+
# +value+ Value of the cookie
|
|
13
|
+
# Optional:
|
|
14
|
+
# +expires+ Time when the cookie should expire. If not specified, the cookie never expires.
|
|
15
|
+
# +path+ Path relative to the application's callback URL, with which the cookie should be associated. (default value is /?
|
|
16
|
+
def set_cookie(user, name, value, expires=nil, path=nil)
|
|
17
|
+
@session.post('facebook.data.setCookie',
|
|
18
|
+
:uid => User.cast_to_facebook_id(user),
|
|
19
|
+
:name => name,
|
|
20
|
+
:value => value,
|
|
21
|
+
:expires => expires,
|
|
22
|
+
:path => path) {|response| response == '1'}
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
##
|
|
26
|
+
# ** BETA ***
|
|
27
|
+
# Gets a cookie stored on Facebook
|
|
28
|
+
# +user+ The user from whom to get the cookies.
|
|
29
|
+
# Optional:
|
|
30
|
+
# +name+ The name of the cookie. If not specified, all the cookies for the given user get returned.
|
|
31
|
+
def get_cookies(user, name=nil)
|
|
32
|
+
@cookies = @session.post(
|
|
33
|
+
'facebook.data.getCookies', :uid => User.cast_to_facebook_id(user), :name => name) do |response|
|
|
34
|
+
response.map do |hash|
|
|
35
|
+
Cookie.from_hash(hash)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
##
|
|
41
|
+
# ** BETA ***
|
|
42
|
+
# Gets a preference stored on Facebook
|
|
43
|
+
# +pref_id+ The id of the preference to get
|
|
44
|
+
def get_preference(pref_id)
|
|
45
|
+
@session.post('facebook.data.getUserPreference', :pref_id=>pref_id)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
##
|
|
49
|
+
# ** BETA ***
|
|
50
|
+
# Sets a preference on Facebook
|
|
51
|
+
# +pref_id+ The id of the preference to set
|
|
52
|
+
# +value+ The value to set for this preference
|
|
53
|
+
def set_preference(pref_id, value)
|
|
54
|
+
@session.post('facebook.data.setUserPreference', :pref_id=>pref_id, :value=>value)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
module Facebooker
|
|
2
|
+
module Feed
|
|
3
|
+
METHODS = {'Action' => 'facebook.feed.publishActionOfUser', 'Story' => 'facebook.feed.publishStoryToUser',
|
|
4
|
+
'TemplatizedAction' => 'facebook.feed.publishTemplatizedAction' }
|
|
5
|
+
|
|
6
|
+
class ActionBase
|
|
7
|
+
1.upto(4) do |num|
|
|
8
|
+
attr_accessor "image_#{num}"
|
|
9
|
+
attr_accessor "image_#{num}_link"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def add_image(image,link=nil)
|
|
13
|
+
1.upto(4) do |num|
|
|
14
|
+
if send("image_#{num}").blank?
|
|
15
|
+
send("image_#{num}=",image)
|
|
16
|
+
send("image_#{num}_link=",link) unless link.nil?
|
|
17
|
+
return num
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
protected
|
|
24
|
+
def image_params
|
|
25
|
+
image_hash = {}
|
|
26
|
+
1.upto(4) do |num|
|
|
27
|
+
image_attribute = "image_#{num}"
|
|
28
|
+
image_link_attribute = image_attribute + "_link"
|
|
29
|
+
self.__send__(image_attribute) ? image_hash[image_attribute] = self.__send__(image_attribute) : nil
|
|
30
|
+
self.__send__(image_link_attribute) ? image_hash[image_link_attribute] = self.__send__(image_link_attribute) : nil
|
|
31
|
+
end
|
|
32
|
+
image_hash
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
##
|
|
37
|
+
# Representation of a templatized action to be published into a user's news feed
|
|
38
|
+
class TemplatizedAction < ActionBase
|
|
39
|
+
attr_accessor :page_actor_id, :title_template, :title_data, :body_template, :body_data, :body_general, :target_ids
|
|
40
|
+
|
|
41
|
+
def to_params
|
|
42
|
+
raise "Must set title_template" if self.title_template.nil?
|
|
43
|
+
{ :page_actor_id => page_actor_id,
|
|
44
|
+
:title_template => title_template,
|
|
45
|
+
:title_data => convert_json(title_data),
|
|
46
|
+
:body_template => body_template,
|
|
47
|
+
:body_data => convert_json(body_data),
|
|
48
|
+
:body_general => body_general,
|
|
49
|
+
:target_ids => target_ids }.merge image_params
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def convert_json(hash_or_string)
|
|
53
|
+
(hash_or_string.is_a?(Hash) and hash_or_string.respond_to?(:to_json)) ? hash_or_string.to_json : hash_or_string
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
##
|
|
58
|
+
# Representation of a story to be published into a user's news feed.
|
|
59
|
+
class Story < ActionBase
|
|
60
|
+
attr_accessor :title, :body
|
|
61
|
+
|
|
62
|
+
##
|
|
63
|
+
# Converts Story to a Hash of its attributes for use as parameters to Facebook REST API calls
|
|
64
|
+
def to_params
|
|
65
|
+
raise "Must set title before converting" if self.title.nil?
|
|
66
|
+
{ :title => title, :body => body }.merge image_params
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
end
|
|
70
|
+
Action = Story.dup
|
|
71
|
+
def Action.name
|
|
72
|
+
"Action"
|
|
73
|
+
end
|
|
74
|
+
##
|
|
75
|
+
# Representation of an action to be published into a user's news feed. Alias for Story.
|
|
76
|
+
class Action; end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
require 'benchmark'
|
|
2
|
+
module Facebooker
|
|
3
|
+
@@logger = nil
|
|
4
|
+
def self.logger=(logger)
|
|
5
|
+
@@logger = logger
|
|
6
|
+
end
|
|
7
|
+
def self.logger
|
|
8
|
+
@@logger
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
module Logging
|
|
12
|
+
@skip_api_logging = nil
|
|
13
|
+
class << self; attr_accessor :skip_api_logging; end
|
|
14
|
+
|
|
15
|
+
def self.log_fb_api(method, params)
|
|
16
|
+
message = method # might customize later
|
|
17
|
+
dump = format_fb_params(params)
|
|
18
|
+
if block_given?
|
|
19
|
+
result = nil
|
|
20
|
+
seconds = Benchmark.realtime { result = yield }
|
|
21
|
+
log_info(message, dump, seconds) unless skip_api_logging
|
|
22
|
+
result
|
|
23
|
+
else
|
|
24
|
+
log_info(message, dump) unless skip_api_logging
|
|
25
|
+
nil
|
|
26
|
+
end
|
|
27
|
+
rescue Exception => e
|
|
28
|
+
exception = "#{e.class.name}: #{e.message}: #{dump}"
|
|
29
|
+
log_info(message, exception)
|
|
30
|
+
raise
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def self.format_fb_params(params)
|
|
34
|
+
params.map { |key,value| "#{key} = #{value}" }.join(', ')
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def self.log_info(message, dump, seconds = 0)
|
|
38
|
+
return unless Facebooker.logger
|
|
39
|
+
log_message = "#{message} (#{seconds}) #{dump}"
|
|
40
|
+
Facebooker.logger.info(log_message)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module Facebooker
|
|
2
|
+
class Mobile
|
|
3
|
+
def initialize(session)
|
|
4
|
+
@session = session
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
# Used to determine whether the user identified by "uid" has enabled SMS for this application.
|
|
8
|
+
def can_send(user)
|
|
9
|
+
@session.post('facebook.sms.canSend', :uid => User.cast_to_facebook_id(user))
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Send the given message to the user.
|
|
13
|
+
# See http://wiki.developers.facebook.com/index.php/Mobile
|
|
14
|
+
def send(user, message)
|
|
15
|
+
@session.post('facebook.sms.send',
|
|
16
|
+
{:uid => User.cast_to_facebook_id(user),
|
|
17
|
+
:message => message}, false)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
require 'digest/md5'
|
|
2
|
+
require 'facebooker/service'
|
|
3
|
+
|
|
4
|
+
module Facebooker
|
|
5
|
+
# A mock service that reads the Facebook response from fixtures
|
|
6
|
+
# Adapted from http://gist.github.com/44344
|
|
7
|
+
#
|
|
8
|
+
# Facebooker::MockService.fixture_path = 'path/to/dir'
|
|
9
|
+
# Facebooker::Session.current = Facebooker::MockSession.create
|
|
10
|
+
#
|
|
11
|
+
class MockService < Service
|
|
12
|
+
class << self
|
|
13
|
+
attr_accessor :fixture_path
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def read_fixture(method, filename, original = nil)
|
|
17
|
+
path = fixture_path(method, filename)
|
|
18
|
+
File.read path
|
|
19
|
+
rescue Errno::ENAMETOOLONG
|
|
20
|
+
read_fixture(method, hash_fixture_name(filename), filename)
|
|
21
|
+
rescue Errno::ENOENT => e
|
|
22
|
+
if File.exists?(fixture_path(method, 'default'))
|
|
23
|
+
File.read fixture_path(method, 'default')
|
|
24
|
+
else
|
|
25
|
+
e.message << "\n(Non-hashed path is #{original})" if original
|
|
26
|
+
e.message << "\nFacebook API Reference: http://wiki.developers.facebook.com/index.php/#{method.sub(/^facebook\./, '')}#Example_Return_XML"
|
|
27
|
+
raise e
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def post(params)
|
|
32
|
+
method = params.delete(:method)
|
|
33
|
+
params.delete_if {|k,_| [:v, :api_key, :call_id, :sig].include?(k) }
|
|
34
|
+
Parser.parse(method, read_fixture(method, fixture_name(params)))
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
def fixture_path(method, filename)
|
|
39
|
+
File.join(self.class.fixture_path, method, "#{filename}.xml")
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def hash_fixture_name(filename)
|
|
43
|
+
Digest::MD5.hexdigest(filename)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def fixture_name(params)
|
|
47
|
+
params.map {|*args| args.join('=') }.sort.join('&')
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|