mmangino-facebooker 1.0.2 → 1.0.3
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/init.rb +16 -0
- data/lib/facebooker/models/user.rb +29 -13
- data/lib/facebooker/parser.rb +9 -2
- data/lib/facebooker/rails/facebook_url_helper.rb +191 -0
- data/test/user_test.rb +30 -6
- metadata +2 -1
data/init.rb
CHANGED
@@ -41,6 +41,22 @@ class ActionController::Routing::Route
|
|
41
41
|
alias_method_chain :recognition_conditions, :facebooker
|
42
42
|
end
|
43
43
|
|
44
|
+
# When making get requests, Facebook sends fb_sig parameters both in the query string
|
45
|
+
# and also in the post body. We want to ignore the query string ones because they are one
|
46
|
+
# request out of date
|
47
|
+
# We only do thise when there are POST parameters so that IFrame linkage still works
|
48
|
+
class ActionController::AbstractRequest
|
49
|
+
def query_parameters_with_facebooker
|
50
|
+
if request_parameters.blank?
|
51
|
+
query_parameters_without_facebooker
|
52
|
+
else
|
53
|
+
(query_parameters_without_facebooker||{}).reject {|key,value| key.to_s =~ /^fb_sig/}
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
alias_method_chain :query_parameters, :facebooker
|
58
|
+
end
|
59
|
+
|
44
60
|
# We turn off route optimization to make named routes use our code for figuring out if they should go to the session
|
45
61
|
# If this fails, it means we're on rails 1.2, we can ignore it
|
46
62
|
begin
|
@@ -43,13 +43,18 @@ module Facebooker
|
|
43
43
|
# Returns a user's events, params correspond to API call parameters (except UID):
|
44
44
|
# http://wiki.developers.facebook.com/index.php/Events.get
|
45
45
|
# E.g:
|
46
|
-
# @user.events(:start_time => Time.now
|
46
|
+
# @user.events(:start_time => Time.now, :end_time => 1.month.from_now)
|
47
47
|
# # => Returns events betwen now and a month from now
|
48
48
|
def events(params={})
|
49
|
-
@events ||=
|
49
|
+
@events ||= {}
|
50
|
+
[:start_time,:end_time].compact.each do |key|
|
51
|
+
params[key] = params[key].to_i
|
52
|
+
end
|
53
|
+
# puts @events[params.to_s].nil?
|
54
|
+
@events[params.to_s] ||= @session.post('facebook.events.get', {:uid => self.id}.merge(params)).map do |event|
|
50
55
|
Event.from_hash(event)
|
51
56
|
end
|
52
|
-
end
|
57
|
+
end
|
53
58
|
|
54
59
|
#
|
55
60
|
# Set the list of friends, given an array of User objects. If the list has been retrieved previously, will not set
|
@@ -219,24 +224,35 @@ module Facebooker
|
|
219
224
|
end
|
220
225
|
|
221
226
|
##
|
222
|
-
#
|
223
|
-
#
|
224
|
-
# DOES NOT prepend "is" to the message
|
225
|
-
#
|
226
|
-
# requires extended permission.
|
227
|
+
# This DOES NOT set the status of a user on Facebook
|
228
|
+
# Use the set_status method instead
|
227
229
|
def status=(message)
|
228
230
|
case message
|
229
|
-
when String
|
230
|
-
session.post('facebook.users.setStatus',:status=>message,:status_includes_verb=>1) do |ret|
|
231
|
-
ret
|
232
|
-
end
|
233
|
-
when Status
|
231
|
+
when String,Status
|
234
232
|
@status = message
|
235
233
|
when Hash
|
236
234
|
@status = Status.from_hash(message)
|
237
235
|
end
|
238
236
|
end
|
239
237
|
|
238
|
+
##
|
239
|
+
# Set the status for a user
|
240
|
+
# DOES NOT prepend "is" to the message
|
241
|
+
#
|
242
|
+
# requires extended permission.
|
243
|
+
def set_status(message)
|
244
|
+
self.status=message
|
245
|
+
session.post('facebook.users.setStatus',:status=>message,:status_includes_verb=>1) do |ret|
|
246
|
+
ret
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
##
|
251
|
+
# Checks to see if the user has enabled the given extended permission
|
252
|
+
def has_permission?(ext_perm) # ext_perm = email, offline_access, status_update, photo_upload, create_listing, create_event, rsvp_event, sms
|
253
|
+
session.post('facebook.users.hasAppPermission',:ext_perm=>ext_perm) == "1"
|
254
|
+
end
|
255
|
+
|
240
256
|
##
|
241
257
|
# Convenience method to send email to the current user
|
242
258
|
def send_email(subject, text=nil, fbml=nil)
|
data/lib/facebooker/parser.rb
CHANGED
@@ -401,8 +401,8 @@ module Facebooker
|
|
401
401
|
memo
|
402
402
|
end
|
403
403
|
end
|
404
|
-
|
405
|
-
|
404
|
+
|
405
|
+
private
|
406
406
|
def self.are_friends?(raw_value)
|
407
407
|
if raw_value == '1'
|
408
408
|
true
|
@@ -432,6 +432,12 @@ module Facebooker
|
|
432
432
|
end
|
433
433
|
end
|
434
434
|
|
435
|
+
class UserHasPermission < Parser
|
436
|
+
def self.process(data)
|
437
|
+
element('users_hasAppPermission_response', data).text_value
|
438
|
+
end
|
439
|
+
end
|
440
|
+
|
435
441
|
class Errors < Parser#:nodoc:
|
436
442
|
EXCEPTIONS = {
|
437
443
|
1 => Facebooker::Session::UnknownError,
|
@@ -492,6 +498,7 @@ module Facebooker
|
|
492
498
|
'facebook.users.getStandardInfo' => UserStandardInfo,
|
493
499
|
'facebook.users.setStatus' => SetStatus,
|
494
500
|
'facebook.users.getLoggedInUser' => GetLoggedInUser,
|
501
|
+
'facebook.users.hasAppPermission' => UserHasPermission,
|
495
502
|
'facebook.pages.isAdmin' => PagesIsAdmin,
|
496
503
|
'facebook.pages.getInfo' => PagesGetInfo,
|
497
504
|
'facebook.friends.get' => GetFriends,
|
@@ -0,0 +1,191 @@
|
|
1
|
+
# Extends the ActionView::Helpers::UrlHelper module. See it for details on
|
2
|
+
# the usual url helper methods: url_for, link_to, button_to, etc.
|
3
|
+
#
|
4
|
+
# Mostly, the changes sanitize javascript into facebook javascript.
|
5
|
+
# It sanitizes link_to solely by altering the private methods:
|
6
|
+
# convert_options_to_javascript!, confirm_javascript_function, and
|
7
|
+
# method_javascript_function. For button_to, it alters button_to
|
8
|
+
# itself, as well as confirm_javascript_function. No other methods
|
9
|
+
# need to be changed because of Facebook javascript.
|
10
|
+
#
|
11
|
+
# For button_to and link_to, adds alternate confirm options for facebook.
|
12
|
+
# ==== Options
|
13
|
+
# * <tt>:confirm => 'question?'</tt> - This will add a JavaScript confirm
|
14
|
+
# prompt with the question specified.
|
15
|
+
#
|
16
|
+
# Example:
|
17
|
+
# # Generates: <a href="http://rubyforge.org/projects/facebooker" onclick="
|
18
|
+
# # var dlg = new Dialog().showChoice('Please Confirm', 'Go to Facebooker?').setStyle();
|
19
|
+
# # var a=this;dlg.onconfirm = function() {
|
20
|
+
# # document.setLocation(a.getHref());
|
21
|
+
# # }; return false;">Facebooker</a>
|
22
|
+
# link_to("Facebooker", "http://rubyforge.org/projects/facebooker", :confirm=>"Go to Facebooker?")
|
23
|
+
#
|
24
|
+
# Alternatively, options[:confirm] may be specified.
|
25
|
+
# See the Facebook page http://wiki.developers.facebook.com/index.php/FBJS.
|
26
|
+
# These options are:
|
27
|
+
# <tt>:title</tt>:: Specifies the title of the Facebook dialog. Default is "Please Confirm".
|
28
|
+
# <tt>:content</tt>:: Specifies the title of the Facebook dialog. Default is "Are you sure?".
|
29
|
+
#
|
30
|
+
# Example:
|
31
|
+
# # Generates: <a href="http://rubyforge.org/projects/facebooker" onclick="
|
32
|
+
# # var dlg = new Dialog().showChoice('the page says:', 'Go to Facebooker?').setStyle();
|
33
|
+
# # var a=this;dlg.onconfirm = function() {
|
34
|
+
# # document.setLocation(a.getHref());
|
35
|
+
# # }; return false;">Facebooker</a>
|
36
|
+
# link_to("Facebooker", "http://rubyforge.org/projects/facebooker", :confirm=>{:title=>"the page says:", :content=>"Go to Facebooker?"})
|
37
|
+
#
|
38
|
+
# Any other options passed are assumed to be css styles.
|
39
|
+
# Again, see the Facebook page http://wiki.developers.facebook.com/index.php/FBJS.
|
40
|
+
#
|
41
|
+
# Example:
|
42
|
+
# # Generates: <a href="http://rubyforge.org/projects/facebooker" onclick="
|
43
|
+
# # var dlg = new Dialog().showChoice('the page says:', 'Are you sure?').setStyle({color: 'pink', width: '200px'});
|
44
|
+
# # var a=this;dlg.onconfirm = function() {
|
45
|
+
# # document.setLocation(a.getHref());
|
46
|
+
# # }; return false;">Facebooker</a>
|
47
|
+
# link_to("Facebooker", "http://rubyforge.org/projects/facebooker", :confirm=>{:title=>"the page says:, :color=>"pink", :width=>"200px"})
|
48
|
+
module ActionView
|
49
|
+
module Helpers
|
50
|
+
module UrlHelper
|
51
|
+
# Alters one and only one line of the Rails button_to. See below.
|
52
|
+
def button_to_with_facebooker(name, options={}, html_options = {})
|
53
|
+
if !request_comes_from_facebook?
|
54
|
+
button_to_without_facebooker(name,options,html_options)
|
55
|
+
else
|
56
|
+
html_options = html_options.stringify_keys
|
57
|
+
convert_boolean_attributes!(html_options, %w( disabled ))
|
58
|
+
|
59
|
+
method_tag = ''
|
60
|
+
if (method = html_options.delete('method')) && %w{put delete}.include?(method.to_s)
|
61
|
+
method_tag = tag('input', :type => 'hidden', :name => '_method', :value => method.to_s)
|
62
|
+
end
|
63
|
+
|
64
|
+
form_method = method.to_s == 'get' ? 'get' : 'post'
|
65
|
+
|
66
|
+
request_token_tag = ''
|
67
|
+
if form_method == 'post' && protect_against_forgery?
|
68
|
+
request_token_tag = tag(:input, :type => "hidden", :name => request_forgery_protection_token.to_s, :value => form_authenticity_token)
|
69
|
+
end
|
70
|
+
|
71
|
+
if confirm = html_options.delete("confirm")
|
72
|
+
# this line is the only change => html_options["onclick"] = "return #{confirm_javascript_function(confirm)}"
|
73
|
+
html_options["onclick"] = "#{confirm_javascript_function(confirm, 'a.getForm().submit();')}return false;"
|
74
|
+
end
|
75
|
+
|
76
|
+
url = options.is_a?(String) ? options : self.url_for(options)
|
77
|
+
name ||= url
|
78
|
+
|
79
|
+
html_options.merge!("type" => "submit", "value" => name)
|
80
|
+
|
81
|
+
"<form method=\"#{form_method}\" action=\"#{escape_once url}\" class=\"button-to\"><div>" +
|
82
|
+
method_tag + tag("input", html_options) + request_token_tag + "</div></form>"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
alias_method_chain :button_to, :facebooker
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
# Altered to throw an error on :popup and sanitize the javascript
|
91
|
+
# for Facebook.
|
92
|
+
def convert_options_to_javascript_with_facebooker!(html_options, url ='')
|
93
|
+
if !request_comes_from_facebook?
|
94
|
+
convert_options_to_javascript_without_facebooker!(html_options,url)
|
95
|
+
else
|
96
|
+
confirm, popup = html_options.delete("confirm"), html_options.delete("popup")
|
97
|
+
|
98
|
+
method, href = html_options.delete("method"), html_options['href']
|
99
|
+
|
100
|
+
html_options["onclick"] = case
|
101
|
+
when popup
|
102
|
+
raise ActionView::ActionViewError, "You can't use :popup"
|
103
|
+
when method # or maybe (confirm and method)
|
104
|
+
"#{method_javascript_function(method, url, href, confirm)}return false;"
|
105
|
+
when confirm # and only confirm
|
106
|
+
"#{confirm_javascript_function(confirm)}return false;"
|
107
|
+
else
|
108
|
+
html_options["onclick"]
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
alias_method_chain :convert_options_to_javascript!, :facebooker
|
114
|
+
|
115
|
+
|
116
|
+
# Overrides a private method that link_to calls via convert_options_to_javascript! and
|
117
|
+
# also, button_to calls directly. For Facebook, confirm can be a hash of options to
|
118
|
+
# stylize the Facebook dialog. Takes :title, :content, :style options. See
|
119
|
+
# the Facebook page http://wiki.developers.facebook.com/index.php/FBJS for valid
|
120
|
+
# style formats like "color: 'black', background: 'white'" or like "'color','black'".
|
121
|
+
#
|
122
|
+
# == Examples ==
|
123
|
+
#
|
124
|
+
# link_to("Facebooker", "http://rubyforge.org/projects/facebooker", :confirm=>"Go to Facebooker?")
|
125
|
+
# link_to("Facebooker", "http://rubyforge.org/projects/facebooker", :confirm=>{:title=>"the page says:, :content=>"Go to Facebooker?"})
|
126
|
+
# link_to("Facebooker", "http://rubyforge.org/projects/facebooker", :confirm=>{:title=>"the page says:, :content=>"Go to Facebooker?", :color=>"pink"})
|
127
|
+
def confirm_javascript_function_with_facebooker(confirm, fun = nil)
|
128
|
+
if !request_comes_from_facebook?
|
129
|
+
confirm_javascript_function_without_facebooker(confirm)
|
130
|
+
else
|
131
|
+
if(confirm.is_a?(Hash))
|
132
|
+
confirm_options = confirm.stringify_keys
|
133
|
+
title = confirm_options.delete("title") || "Please Confirm"
|
134
|
+
content = confirm_options.delete("content") || "Are you sure?"
|
135
|
+
style = confirm_options.empty? ? "" : convert_options_to_css(confirm_options)
|
136
|
+
else
|
137
|
+
title,content,style = 'Please Confirm', confirm, ""
|
138
|
+
end
|
139
|
+
|
140
|
+
"var dlg = new Dialog().showChoice('#{escape_javascript(title.to_s)}','#{escape_javascript(content.to_s)}').setStyle(#{style});"+
|
141
|
+
"var a=this;dlg.onconfirm = function() { #{fun ? fun : 'document.setLocation(a.getHref());'} };"
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
alias_method_chain :confirm_javascript_function, :facebooker
|
146
|
+
|
147
|
+
def convert_options_to_css(options)
|
148
|
+
key_pair = options.shift
|
149
|
+
style = "{#{key_pair[0]}: '#{key_pair[1]}'"
|
150
|
+
for key in options.keys
|
151
|
+
style << ", #{key}: '#{options[key]}'"
|
152
|
+
end
|
153
|
+
style << "}"
|
154
|
+
end
|
155
|
+
|
156
|
+
# Dynamically creates a form for link_to with method. Calls confirm_javascript_function if and
|
157
|
+
# only if (confirm && method) for link_to
|
158
|
+
def method_javascript_function_with_facebooker(method, url = '', href = nil, confirm = nil)
|
159
|
+
if !request_comes_from_facebook?
|
160
|
+
method_javascript_function_without_facebooker(method,url,href)
|
161
|
+
else
|
162
|
+
action = (href && url.size > 0) ? "'#{url}'" : 'a.getHref()'
|
163
|
+
submit_function =
|
164
|
+
"var f = document.createElement('form'); f.setStyle('display','none'); " +
|
165
|
+
"a.getParentNode().appendChild(f); f.setMethod('POST'); f.setAction(#{action});"
|
166
|
+
|
167
|
+
unless method == :post
|
168
|
+
submit_function << "var m = document.createElement('input'); m.setType('hidden'); "
|
169
|
+
submit_function << "m.setName('_method'); m.setValue('#{method}'); f.appendChild(m);"
|
170
|
+
end
|
171
|
+
|
172
|
+
if protect_against_forgery?
|
173
|
+
submit_function << "var s = document.createElement('input'); s.setType('hidden'); "
|
174
|
+
submit_function << "s.setName('#{request_forgery_protection_token}'); s.setValue('#{escape_javascript form_authenticity_token}'); f.appendChild(s);"
|
175
|
+
end
|
176
|
+
submit_function << "f.submit();"
|
177
|
+
|
178
|
+
if(confirm)
|
179
|
+
confirm_javascript_function(confirm, submit_function)
|
180
|
+
else
|
181
|
+
"var a=this;" + submit_function
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
alias_method_chain :method_javascript_function, :facebooker
|
187
|
+
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
data/test/user_test.rb
CHANGED
@@ -15,6 +15,11 @@ class UserTest < Test::Unit::TestCase
|
|
15
15
|
@user.friends = [@other_user]
|
16
16
|
end
|
17
17
|
|
18
|
+
def test_has_permission
|
19
|
+
expect_http_posts_with_responses(has_app_permission_response_xml)
|
20
|
+
assert @user.has_permission?("status_update")
|
21
|
+
end
|
22
|
+
|
18
23
|
def test_can_ask_user_if_he_or_she_is_friends_with_another_user
|
19
24
|
assert(@user.friends_with?(@other_user))
|
20
25
|
end
|
@@ -109,9 +114,13 @@ class UserTest < Test::Unit::TestCase
|
|
109
114
|
@user.send_email("subject", nil, "body fbml")
|
110
115
|
end
|
111
116
|
|
117
|
+
def test_doesnt_post_to_facebook_when_assigning_status
|
118
|
+
@session.expects(:post).never
|
119
|
+
@user.status="my status"
|
120
|
+
end
|
112
121
|
def test_can_set_status_with_string
|
113
122
|
@session.expects(:post).with('facebook.users.setStatus', :status=>"my status",:status_includes_verb=>1)
|
114
|
-
@user.
|
123
|
+
@user.set_status("my status")
|
115
124
|
end
|
116
125
|
|
117
126
|
def test_get_events
|
@@ -120,12 +129,18 @@ class UserTest < Test::Unit::TestCase
|
|
120
129
|
events = @user.events
|
121
130
|
assert_equal "29511517904", events.first.eid
|
122
131
|
end
|
123
|
-
|
124
|
-
def
|
125
|
-
@user.
|
126
|
-
@
|
132
|
+
|
133
|
+
def test_events_caching_honors_params
|
134
|
+
@user = Facebooker::User.new(9507801, @session)
|
135
|
+
@session.expects(:post).returns([{:eid=>1}])
|
136
|
+
assert_equal 1,@user.events.first.eid
|
137
|
+
@session.expects(:post).returns([{:eid=>2}])
|
138
|
+
assert_equal 2,@user.events(:start_time=>1.day.ago).first.eid
|
139
|
+
@session.expects(:post).never
|
140
|
+
assert_equal 1,@user.events.first.eid
|
127
141
|
end
|
128
142
|
|
143
|
+
|
129
144
|
def test_to_s
|
130
145
|
assert_equal("1234",@user.to_s)
|
131
146
|
end
|
@@ -226,4 +241,13 @@ class UserTest < Test::Unit::TestCase
|
|
226
241
|
</connect_registerUsers_response>
|
227
242
|
XML
|
228
243
|
end
|
229
|
-
|
244
|
+
|
245
|
+
def has_app_permission_response_xml
|
246
|
+
<<-XML
|
247
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
248
|
+
<users_hasAppPermission_response xmlns="http://api.facebook.com/1.0/"
|
249
|
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
250
|
+
xsi:schemaLocation="http://api.facebook.com/1.0/ http://api.facebook.com/1.0/facebook.xsd">1</users_hasAppPermission_response>
|
251
|
+
XML
|
252
|
+
end
|
253
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mmangino-facebooker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chad Fowler
|
@@ -115,6 +115,7 @@ files:
|
|
115
115
|
- lib/facebooker/rails/facebook_pretty_errors.rb
|
116
116
|
- lib/facebooker/rails/facebook_request_fix.rb
|
117
117
|
- lib/facebooker/rails/facebook_session_handling.rb
|
118
|
+
- lib/facebooker/rails/facebook_url_helper.rb
|
118
119
|
- lib/facebooker/rails/facebook_url_rewriting.rb
|
119
120
|
- lib/facebooker/rails/helpers.rb
|
120
121
|
- lib/facebooker/rails/profile_publisher_extensions.rb
|