rfacebook 0.7.1 → 0.8.0
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/lib/facebook_rails_controller_extensions.rb +3 -184
- data/lib/facebook_session.rb +13 -0
- data/lib/facepricot.rb +1 -9
- data/lib/rfacebook_on_rails/controller_extensions.rb +272 -0
- data/lib/rfacebook_on_rails/model_extensions.rb +173 -0
- data/lib/rfacebook_on_rails/plugin/Rakefile.rb +1 -0
- data/lib/rfacebook_on_rails/plugin/init.rb +82 -0
- data/lib/rfacebook_on_rails/plugin/install.rb +1 -0
- data/lib/rfacebook_on_rails/plugin/rake.rb +144 -0
- data/lib/rfacebook_on_rails/plugin/uninstall.rb +1 -0
- data/lib/rfacebook_on_rails/status_manager.rb +309 -0
- data/lib/rfacebook_on_rails/templates/debug_panel.rb +210 -0
- data/lib/rfacebook_on_rails/view_extensions.rb +64 -0
- metadata +16 -3
@@ -1,188 +1,7 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
#
|
4
|
-
# Redistribution and use in source and binary forms, with or without modification,
|
5
|
-
# are permitted provided that the following conditions are met:
|
6
|
-
#
|
7
|
-
# Redistributions of source code must retain the above copyright notice,
|
8
|
-
# this list of conditions and the following disclaimer.
|
9
|
-
#
|
10
|
-
# Redistributions in binary form must reproduce the above copyright notice,
|
11
|
-
# this list of conditions and the following disclaimer in the documentation
|
12
|
-
# and/or other materials provided with the distribution.
|
13
|
-
#
|
14
|
-
# Neither the name of the original author nor the names of contributors
|
15
|
-
# may be used to endorse or promote products derived from this software
|
16
|
-
# without specific prior written permission.
|
17
|
-
#
|
18
|
-
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
19
|
-
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
20
|
-
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
21
|
-
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
22
|
-
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
23
|
-
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
24
|
-
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
25
|
-
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
26
|
-
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
27
|
-
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
28
|
-
#
|
29
|
-
|
30
|
-
require "facebook_web_session"
|
31
|
-
|
1
|
+
# This file is deprecated, but remains here for backward compatibility
|
2
|
+
require "rfacebook_on_rails/controller_extensions"
|
32
3
|
module RFacebook
|
33
|
-
|
34
4
|
module RailsControllerExtensions
|
35
|
-
|
36
|
-
# SECTION: StandardErrors
|
37
|
-
|
38
|
-
class APIKeyNeededStandardError < StandardError; end
|
39
|
-
class APISecretNeededStandardError < StandardError; end
|
40
|
-
class APIFinisherNeededStandardError < StandardError; end
|
41
|
-
|
42
|
-
# SECTION: Template Methods (must be implemented by concrete subclass)
|
43
|
-
|
44
|
-
def facebook_api_key
|
45
|
-
raise APIKeyNeededStandardError
|
46
|
-
end
|
47
|
-
|
48
|
-
def facebook_api_secret
|
49
|
-
raise APISecretNeededStandardError
|
50
|
-
end
|
51
|
-
|
52
|
-
def finish_facebook_login
|
53
|
-
raise APIFinisherNeededStandardError
|
54
|
-
end
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
# SECTION: Required Methods
|
59
|
-
|
60
|
-
def fbparams
|
61
|
-
|
62
|
-
dup_params = (self.params || {}).dup
|
63
|
-
|
64
|
-
# try to get fbparams from the params hash
|
65
|
-
if (!@fbparams || @fbparams.length <= 0)
|
66
|
-
@fbparams = fbsession.get_fb_sig_params(dup_params)
|
67
|
-
end
|
68
|
-
|
69
|
-
# else, try to get fbparams from the cookies hash
|
70
|
-
# TODO: we don't write anything into the cookie, so this is kind of pointless right now
|
71
|
-
if (@fbparams.length <= 0)
|
72
|
-
@fbparams = fbsession.get_fb_sig_params(cookies)
|
73
|
-
end
|
74
|
-
|
75
|
-
return @fbparams
|
76
|
-
|
77
|
-
end
|
78
|
-
|
79
|
-
def fbsession
|
80
|
-
|
81
|
-
if !@fbsession
|
82
|
-
|
83
|
-
# create a session no matter what
|
84
|
-
@fbsession = FacebookWebSession.new(facebook_api_key, facebook_api_secret)
|
85
|
-
|
86
|
-
# then try to activate it somehow (or retrieve from previous state)
|
87
|
-
# these might be nil
|
88
|
-
facebookUid = fbparams["user"]
|
89
|
-
facebookSessionKey = fbparams["session_key"]
|
90
|
-
expirationTime = fbparams["expires"]
|
91
|
-
|
92
|
-
if (facebookUid and facebookSessionKey and expirationTime)
|
93
|
-
# Method 1: we have the user id and key from the fb_sig_ params
|
94
|
-
@fbsession.activate_with_previous_session(facebookSessionKey, facebookUid, expirationTime)
|
95
|
-
|
96
|
-
elsif (!in_facebook_canvas? and session[:rfacebook_fbsession])
|
97
|
-
# Method 2: we've logged in the user already
|
98
|
-
@fbsession = session[:rfacebook_fbsession]
|
99
|
-
|
100
|
-
end
|
101
|
-
|
102
|
-
end
|
103
|
-
|
104
|
-
return @fbsession
|
105
|
-
|
106
|
-
end
|
107
|
-
|
108
|
-
# SECTION: Helpful Methods
|
109
|
-
|
110
|
-
def facebook_redirect_to(url)
|
111
|
-
if in_facebook_canvas?
|
112
|
-
render :text => "<fb:redirect url=\"#{url}\" />"
|
113
|
-
elsif url =~ /^https?:\/\/([^\/]*\.)?facebook\.com(:\d+)?/i
|
114
|
-
render :text => "<script type=\"text/javascript\">\ntop.location.href = \"#{url}\";\n</script>";
|
115
|
-
else
|
116
|
-
redirect_to url
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
def in_facebook_canvas?
|
121
|
-
return (fbparams["in_canvas"] != nil)
|
122
|
-
end
|
123
|
-
|
124
|
-
def in_facebook_frame?
|
125
|
-
return (fbparams["in_iframe"] != nil || fbparams["in_canvas"] != nil)
|
126
|
-
end
|
127
|
-
|
128
|
-
def handle_facebook_login
|
129
|
-
|
130
|
-
if (params["auth_token"] and !in_facebook_canvas?)
|
131
|
-
|
132
|
-
# create a session
|
133
|
-
session[:rfacebook_fbsession] = FacebookWebSession.new(facebook_api_key, facebook_api_secret)
|
134
|
-
session[:rfacebook_fbsession].activate_with_token(params["auth_token"])
|
135
|
-
|
136
|
-
# template method call upon success
|
137
|
-
if session[:rfacebook_fbsession].is_valid?
|
138
|
-
RAILS_DEFAULT_LOGGER.debug "** rfacebook: Login was successful, calling finish_facebook_login"
|
139
|
-
finish_facebook_login
|
140
|
-
end
|
141
|
-
|
142
|
-
else
|
143
|
-
RAILS_DEFAULT_LOGGER.debug "** rfacebook: Didn't activate session from handle_facebook_login"
|
144
|
-
end
|
145
|
-
|
146
|
-
end
|
147
|
-
|
148
|
-
def require_facebook_login
|
149
|
-
|
150
|
-
# handle a facebook login if given (external sites and iframe only)
|
151
|
-
handle_facebook_login
|
152
|
-
|
153
|
-
if !performed?
|
154
|
-
|
155
|
-
RAILS_DEFAULT_LOGGER.debug "** rfacebook: Rendering has not been performed"
|
156
|
-
|
157
|
-
# try to get the session
|
158
|
-
sess = fbsession
|
159
|
-
|
160
|
-
# handle invalid sessions by forcing the user to log in
|
161
|
-
if !sess.is_valid?
|
162
|
-
|
163
|
-
RAILS_DEFAULT_LOGGER.debug "** rfacebook: Session is not valid"
|
164
|
-
|
165
|
-
if in_facebook_canvas?
|
166
|
-
RAILS_DEFAULT_LOGGER.debug "** rfacebook: Rendering canvas redirect"
|
167
|
-
render :text => "<fb:redirect url=\"#{sess.get_login_url(:canvas=>true)}\" />"
|
168
|
-
return false
|
169
|
-
else
|
170
|
-
RAILS_DEFAULT_LOGGER.debug "** rfacebook: Redirecting to login"
|
171
|
-
redirect_to sess.get_login_url
|
172
|
-
return false
|
173
|
-
end
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
|
-
end
|
178
|
-
|
179
|
-
def require_facebook_install
|
180
|
-
sess = fbsession
|
181
|
-
if (in_facebook_canvas? and (!sess.is_valid? or (fbparams["added"].to_i != 1)))
|
182
|
-
render :text => "<fb:redirect url=\"#{sess.get_install_url}\" />"
|
183
|
-
end
|
184
|
-
end
|
185
|
-
|
5
|
+
include RFacebook::Rails::ControllerExtensions
|
186
6
|
end
|
187
|
-
|
188
7
|
end
|
data/lib/facebook_session.rb
CHANGED
@@ -89,6 +89,9 @@ class FacebookSession
|
|
89
89
|
# cache object for API calls
|
90
90
|
@callcache = {}
|
91
91
|
|
92
|
+
# default to XML formatted responses
|
93
|
+
# @response_format = "XML"
|
94
|
+
|
92
95
|
end
|
93
96
|
|
94
97
|
def session_expired?
|
@@ -125,6 +128,14 @@ class FacebookSession
|
|
125
128
|
return session_user_id
|
126
129
|
end
|
127
130
|
|
131
|
+
# def use_json
|
132
|
+
# @response_format = "JSON"
|
133
|
+
# end
|
134
|
+
#
|
135
|
+
# def use_xml
|
136
|
+
# @response_format = "XML"
|
137
|
+
# end
|
138
|
+
|
128
139
|
# SECTION: Protected Abstract Interface
|
129
140
|
protected
|
130
141
|
|
@@ -192,6 +203,8 @@ class FacebookSession
|
|
192
203
|
params = {}
|
193
204
|
end
|
194
205
|
params = params.dup # patch courtesy of Project Agape
|
206
|
+
|
207
|
+
# params[:format] ||= @response_format
|
195
208
|
params[:method] = "facebook.#{method}"
|
196
209
|
params[:api_key] = @api_key
|
197
210
|
params[:v] = "1.0"
|
data/lib/facepricot.rb
CHANGED
@@ -94,11 +94,7 @@ module RFacebook
|
|
94
94
|
def hpricot
|
95
95
|
return @doc
|
96
96
|
end
|
97
|
-
|
98
|
-
# def to_hash
|
99
|
-
# return HpricotHashWrapper.new(@doc.containers[0]).to_hash
|
100
|
-
# end
|
101
|
-
|
97
|
+
|
102
98
|
end
|
103
99
|
|
104
100
|
class FacepricotChain < String
|
@@ -114,10 +110,6 @@ module RFacebook
|
|
114
110
|
return make_facepricot_chain(methodSymbol.to_s, @doc)
|
115
111
|
end
|
116
112
|
|
117
|
-
# def to_hash
|
118
|
-
# return HpricotHashWrapper.new(@doc).to_hash
|
119
|
-
# end
|
120
|
-
|
121
113
|
end
|
122
114
|
|
123
115
|
|
@@ -0,0 +1,272 @@
|
|
1
|
+
# Copyright (c) 2007, Matt Pizzimenti (www.livelearncode.com)
|
2
|
+
# All rights reserved.
|
3
|
+
#
|
4
|
+
# Redistribution and use in source and binary forms, with or without modification,
|
5
|
+
# are permitted provided that the following conditions are met:
|
6
|
+
#
|
7
|
+
# Redistributions of source code must retain the above copyright notice,
|
8
|
+
# this list of conditions and the following disclaimer.
|
9
|
+
#
|
10
|
+
# Redistributions in binary form must reproduce the above copyright notice,
|
11
|
+
# this list of conditions and the following disclaimer in the documentation
|
12
|
+
# and/or other materials provided with the distribution.
|
13
|
+
#
|
14
|
+
# Neither the name of the original author nor the names of contributors
|
15
|
+
# may be used to endorse or promote products derived from this software
|
16
|
+
# without specific prior written permission.
|
17
|
+
#
|
18
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
19
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
20
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
21
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
22
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
23
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
24
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
25
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
26
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
27
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
28
|
+
#
|
29
|
+
|
30
|
+
require "facebook_web_session"
|
31
|
+
require "rfacebook_on_rails/status_manager"
|
32
|
+
require "rfacebook_on_rails/templates/debug_panel"
|
33
|
+
|
34
|
+
module RFacebook
|
35
|
+
module Rails
|
36
|
+
module ControllerExtensions
|
37
|
+
|
38
|
+
# SECTION: StandardErrors
|
39
|
+
|
40
|
+
class APIKeyNeededStandardError < StandardError; end
|
41
|
+
class APISecretNeededStandardError < StandardError; end
|
42
|
+
class APICanvasPathNeededStandardError < StandardError; end
|
43
|
+
class APICallbackNeededStandardError < StandardError; end
|
44
|
+
class APIFinisherNeededStandardError < StandardError; end
|
45
|
+
|
46
|
+
# SECTION: Template Methods (must be implemented by concrete subclass)
|
47
|
+
|
48
|
+
def facebook_api_key
|
49
|
+
raise APIKeyNeededStandardError
|
50
|
+
end
|
51
|
+
|
52
|
+
def facebook_api_secret
|
53
|
+
raise APISecretNeededStandardError
|
54
|
+
end
|
55
|
+
|
56
|
+
def facebook_canvas_path
|
57
|
+
raise APICanvasPathNeededStandardError
|
58
|
+
end
|
59
|
+
|
60
|
+
def facebook_callback_path
|
61
|
+
raise APICallbackNeededStandardError
|
62
|
+
end
|
63
|
+
|
64
|
+
def finish_facebook_login
|
65
|
+
raise APIFinisherNeededStandardError
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
|
70
|
+
# SECTION: Required Methods
|
71
|
+
|
72
|
+
def fbparams
|
73
|
+
|
74
|
+
dup_params = (self.params || {}).dup
|
75
|
+
|
76
|
+
# try to get fbparams from the params hash
|
77
|
+
if (!@fbparams || @fbparams.length <= 0)
|
78
|
+
@fbparams = fbsession.get_fb_sig_params(dup_params)
|
79
|
+
end
|
80
|
+
|
81
|
+
# else, try to get fbparams from the cookies hash
|
82
|
+
# TODO: we don't write anything into the cookie, so this is kind of pointless right now
|
83
|
+
if (@fbparams.length <= 0)
|
84
|
+
@fbparams = fbsession.get_fb_sig_params(cookies)
|
85
|
+
end
|
86
|
+
|
87
|
+
# TODO: fb_sig_params now includes all friend ids by default, so we can avoid an API call to friends.get
|
88
|
+
# we should extend FacebookWebSession for Rails to make this optimization
|
89
|
+
|
90
|
+
return @fbparams
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
def fbsession
|
95
|
+
|
96
|
+
if !@fbsession
|
97
|
+
|
98
|
+
# create a session no matter what
|
99
|
+
@fbsession = FacebookWebSession.new(facebook_api_key, facebook_api_secret)
|
100
|
+
|
101
|
+
# then try to activate it somehow (or retrieve from previous state)
|
102
|
+
# these might be nil
|
103
|
+
facebookUid = fbparams["user"]
|
104
|
+
facebookSessionKey = fbparams["session_key"]
|
105
|
+
expirationTime = fbparams["expires"]
|
106
|
+
|
107
|
+
if (facebookUid and facebookSessionKey and expirationTime)
|
108
|
+
# Method 1: we have the user id and key from the fb_sig_ params
|
109
|
+
@fbsession.activate_with_previous_session(facebookSessionKey, facebookUid, expirationTime)
|
110
|
+
|
111
|
+
elsif (!in_facebook_canvas? and session[:rfacebook_fbsession])
|
112
|
+
# Method 2: we've logged in the user already
|
113
|
+
@fbsession = session[:rfacebook_fbsession]
|
114
|
+
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
|
119
|
+
return @fbsession
|
120
|
+
|
121
|
+
end
|
122
|
+
|
123
|
+
# SECTION: Helpful Methods
|
124
|
+
|
125
|
+
def facebook_redirect_to(url)
|
126
|
+
if in_facebook_canvas?
|
127
|
+
render :text => "<fb:redirect url=\"#{url}\" />"
|
128
|
+
elsif url =~ /^https?:\/\/([^\/]*\.)?facebook\.com(:\d+)?/i
|
129
|
+
render :text => "<script type=\"text/javascript\">\ntop.location.href = \"#{url}\";\n</script>";
|
130
|
+
else
|
131
|
+
redirect_to url
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def in_facebook_canvas?
|
136
|
+
return (params["fb_sig_in_canvas"] != nil)
|
137
|
+
end
|
138
|
+
|
139
|
+
def in_facebook_frame?
|
140
|
+
return (params["fb_sig_in_iframe"] != nil || params["fb_sig_in_canvas"] != nil)
|
141
|
+
end
|
142
|
+
|
143
|
+
def in_external_app?
|
144
|
+
return (!params[:fb_sig] and !in_facebook_frame?)
|
145
|
+
end
|
146
|
+
|
147
|
+
def handle_facebook_login
|
148
|
+
|
149
|
+
puts params.inspect
|
150
|
+
|
151
|
+
if (params["auth_token"] and !in_facebook_canvas?)
|
152
|
+
|
153
|
+
# create a session
|
154
|
+
session[:rfacebook_fbsession] = FacebookWebSession.new(facebook_api_key, facebook_api_secret)
|
155
|
+
session[:rfacebook_fbsession].activate_with_token(params["auth_token"])
|
156
|
+
|
157
|
+
# template method call upon success
|
158
|
+
if session[:rfacebook_fbsession].is_valid?
|
159
|
+
RAILS_DEFAULT_LOGGER.debug "** rfacebook: Login was successful, calling finish_facebook_login"
|
160
|
+
finish_facebook_login
|
161
|
+
end
|
162
|
+
|
163
|
+
else
|
164
|
+
RAILS_DEFAULT_LOGGER.debug "** rfacebook: Didn't activate session from handle_facebook_login"
|
165
|
+
end
|
166
|
+
|
167
|
+
end
|
168
|
+
|
169
|
+
def require_facebook_login
|
170
|
+
|
171
|
+
# handle a facebook login if given (external sites and iframe only)
|
172
|
+
handle_facebook_login
|
173
|
+
|
174
|
+
if !performed?
|
175
|
+
|
176
|
+
RAILS_DEFAULT_LOGGER.debug "** rfacebook: Rendering has not been performed"
|
177
|
+
|
178
|
+
# try to get the session
|
179
|
+
sess = fbsession
|
180
|
+
|
181
|
+
# handle invalid sessions by forcing the user to log in
|
182
|
+
if !sess.is_valid?
|
183
|
+
|
184
|
+
RAILS_DEFAULT_LOGGER.debug "** rfacebook: Session is not valid"
|
185
|
+
|
186
|
+
if in_external_app?
|
187
|
+
RAILS_DEFAULT_LOGGER.debug "** rfacebook: Redirecting to login"
|
188
|
+
redirect_to sess.get_login_url
|
189
|
+
return false
|
190
|
+
elsif (!fbparams or fbparams.size == 0)
|
191
|
+
RAILS_DEFAULT_LOGGER.debug "** rfacebook: Failed to activate due to a bad API key or API secret"
|
192
|
+
render_text facebook_debug_panel
|
193
|
+
return false
|
194
|
+
else
|
195
|
+
RAILS_DEFAULT_LOGGER.debug "** rfacebook: Rendering canvas redirect"
|
196
|
+
render :text => "<fb:redirect url=\"#{sess.get_login_url(:canvas=>true)}\" />"
|
197
|
+
return false
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
end
|
203
|
+
|
204
|
+
def require_facebook_install
|
205
|
+
sess = fbsession
|
206
|
+
if (in_facebook_canvas? and (!sess.is_valid? or (fbparams["added"].to_i != 1)))
|
207
|
+
render :text => "<fb:redirect url=\"#{sess.get_install_url}\" />"
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
def self.included(base)
|
212
|
+
|
213
|
+
# FIXME: figure out why this is necessary...for some reason, we
|
214
|
+
# can't just define url_for in the module itself (it never gets called)
|
215
|
+
base.class_eval '
|
216
|
+
|
217
|
+
alias_method(:url_for__ALIASED, :url_for)
|
218
|
+
|
219
|
+
def url_for(options={}, *params)
|
220
|
+
# check options
|
221
|
+
path = url_for__ALIASED(options, *params)
|
222
|
+
if in_facebook_canvas? #TODO: or in_facebook_frame?)
|
223
|
+
path = "#{path}/"
|
224
|
+
if path.starts_with?(self.facebook_callback_path)
|
225
|
+
path.gsub!(self.facebook_callback_path, self.facebook_canvas_path)
|
226
|
+
if !options.has_key?(:only_path)
|
227
|
+
path = "http://apps.facebook.com#{path}"
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
return path
|
233
|
+
end
|
234
|
+
|
235
|
+
'
|
236
|
+
end
|
237
|
+
|
238
|
+
def render_with_facebook_debug_panel(options={})
|
239
|
+
# oldLayout = options[:layout]
|
240
|
+
# options[:layout] = false
|
241
|
+
begin
|
242
|
+
renderedOutput = render_to_string(options)
|
243
|
+
rescue # TODO: don't catch-all here, just the exceptions that we originate
|
244
|
+
renderedOutput = "Errors prevented this page from rendering properly."
|
245
|
+
end
|
246
|
+
# options[:text] = "#{facebook_debug_panel}#{renderedOutput}"
|
247
|
+
# options[:layout] = oldLayout
|
248
|
+
render_text "#{facebook_debug_panel}#{renderedOutput}"
|
249
|
+
end
|
250
|
+
|
251
|
+
def facebook_debug_panel(options={})
|
252
|
+
return ERB.new(RFacebook::Rails::DEBUG_PANEL_ERB_TEMPLATE).result(Proc.new{})
|
253
|
+
end
|
254
|
+
|
255
|
+
def facebook_status_manager
|
256
|
+
checks = [
|
257
|
+
SessionStatusCheck.new(self),
|
258
|
+
(FacebookParamsStatusCheck.new(self) unless (!in_facebook_canvas? and !in_facebook_frame?)),
|
259
|
+
InCanvasStatusCheck.new(self),
|
260
|
+
InFrameStatusCheck.new(self),
|
261
|
+
(CanvasPathStatusCheck.new(self) unless (!in_facebook_canvas? or !in_facebook_frame?)),
|
262
|
+
(CallbackPathStatusCheck.new(self) unless (!in_facebook_canvas? or !in_facebook_frame?)),
|
263
|
+
(FinishFacebookLoginStatusCheck.new(self) unless (in_facebook_canvas? or in_facebook_frame?)),
|
264
|
+
APIKeyStatusCheck.new(self),
|
265
|
+
APISecretStatusCheck.new(self)
|
266
|
+
].compact
|
267
|
+
return StatusManager.new(checks)
|
268
|
+
end
|
269
|
+
|
270
|
+
end
|
271
|
+
end
|
272
|
+
end
|
@@ -0,0 +1,173 @@
|
|
1
|
+
# Copyright (c) 2007, Matt Pizzimenti (www.livelearncode.com)
|
2
|
+
# All rights reserved.
|
3
|
+
#
|
4
|
+
# Redistribution and use in source and binary forms, with or without modification,
|
5
|
+
# are permitted provided that the following conditions are met:
|
6
|
+
#
|
7
|
+
# Redistributions of source code must retain the above copyright notice,
|
8
|
+
# this list of conditions and the following disclaimer.
|
9
|
+
#
|
10
|
+
# Redistributions in binary form must reproduce the above copyright notice,
|
11
|
+
# this list of conditions and the following disclaimer in the documentation
|
12
|
+
# and/or other materials provided with the distribution.
|
13
|
+
#
|
14
|
+
# Neither the name of the original author nor the names of contributors
|
15
|
+
# may be used to endorse or promote products derived from this software
|
16
|
+
# without specific prior written permission.
|
17
|
+
#
|
18
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
19
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
20
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
21
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
22
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
23
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
24
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
25
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
26
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
27
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
28
|
+
#
|
29
|
+
|
30
|
+
|
31
|
+
module RFacebook
|
32
|
+
module Rails
|
33
|
+
module ModelExtensions
|
34
|
+
|
35
|
+
# SECTION: StandardErrors
|
36
|
+
|
37
|
+
class APIKeyNeededStandardError < StandardError; end
|
38
|
+
class APISecretNeededStandardError < StandardError; end
|
39
|
+
|
40
|
+
# SECTION: Template Methods (must be implemented by concrete subclass)
|
41
|
+
|
42
|
+
def facebook_api_key
|
43
|
+
raise APIKeyNeededStandardError
|
44
|
+
end
|
45
|
+
|
46
|
+
def facebook_api_secret
|
47
|
+
raise APISecretNeededStandardError
|
48
|
+
end
|
49
|
+
|
50
|
+
# SECTION: ActsAs method mixing
|
51
|
+
|
52
|
+
def self.included(base)
|
53
|
+
base.extend ActsAsMethods
|
54
|
+
end
|
55
|
+
|
56
|
+
module ActsAsMethods
|
57
|
+
def acts_as_facebook_user
|
58
|
+
include RFacebook::Rails::ModelExtensions::ActsAsFacebookUser::InstanceMethods
|
59
|
+
extend RFacebook::Rails::ModelExtensions::ActsAsFacebookUser::ClassMethods
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
##################################################################
|
65
|
+
##################################################################
|
66
|
+
# SECTION: Acts As Facebook User
|
67
|
+
module ActsAsFacebookUser
|
68
|
+
|
69
|
+
ACTORS = [] # holds a reference to all classes that have ActsAsFacebookUser injected
|
70
|
+
|
71
|
+
FIELDS = [
|
72
|
+
"about_me",
|
73
|
+
"activities",
|
74
|
+
"affiliations",
|
75
|
+
"birthday",
|
76
|
+
"books",
|
77
|
+
"current_location",
|
78
|
+
"education_history",
|
79
|
+
"name",
|
80
|
+
"first_name",
|
81
|
+
"last_name",
|
82
|
+
"hometown_location",
|
83
|
+
"hs_info",
|
84
|
+
"interests",
|
85
|
+
"relationship_status",
|
86
|
+
"meeting_for",
|
87
|
+
"meeting_sex",
|
88
|
+
"movies",
|
89
|
+
"music",
|
90
|
+
"notes_count",
|
91
|
+
"political",
|
92
|
+
"profile_update_time",
|
93
|
+
"quotes",
|
94
|
+
"religion",
|
95
|
+
"sex",
|
96
|
+
"significant_other_id",
|
97
|
+
"status",
|
98
|
+
"timezone",
|
99
|
+
"tv",
|
100
|
+
"wall_count",
|
101
|
+
"work_history",
|
102
|
+
]
|
103
|
+
|
104
|
+
|
105
|
+
######################
|
106
|
+
module ClassMethods
|
107
|
+
|
108
|
+
def find_or_create_by_facebook_session(sess)
|
109
|
+
instance = find_by_facebook_uid(sess.session_user_id)
|
110
|
+
if !instance
|
111
|
+
instance = self.new
|
112
|
+
end
|
113
|
+
instance.facebook_session = sess
|
114
|
+
instance.save
|
115
|
+
return instance
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
|
120
|
+
######################
|
121
|
+
module InstanceMethods
|
122
|
+
|
123
|
+
def facebook_session
|
124
|
+
if !@facebook_session
|
125
|
+
self.facebook_session = FacebookWebSession.new(self.facebook_api_key, self.facebook_api_secret)
|
126
|
+
begin
|
127
|
+
self.facebook_session.activate_with_previous_session(self.facebook_session_key, self.facebook_uid)
|
128
|
+
rescue
|
129
|
+
# not a valid facebook session, should we nil it out?
|
130
|
+
end
|
131
|
+
end
|
132
|
+
return @facebook_session
|
133
|
+
end
|
134
|
+
|
135
|
+
def facebook_session=(sess)
|
136
|
+
@facebook_session = sess
|
137
|
+
self.facebook_session_key = @facebook_session.session_key
|
138
|
+
self.facebook_uid = @facebook_session.session_user_id
|
139
|
+
end
|
140
|
+
|
141
|
+
def has_infinite_session_key?
|
142
|
+
return self.facebook_session_key != nil
|
143
|
+
end
|
144
|
+
|
145
|
+
def self.included(base)
|
146
|
+
ActsAsFacebookUser::ACTORS << base
|
147
|
+
ActsAsFacebookUser::FIELDS.each do |fieldname|
|
148
|
+
base.class_eval <<-end_eval
|
149
|
+
|
150
|
+
def #{fieldname}
|
151
|
+
if facebook_session.is_valid?
|
152
|
+
return facebook_session.cached_users_getInfo(
|
153
|
+
:uids => [facebook_uid],
|
154
|
+
:fields => ActsAsFacebookUser::FIELDS).user.send(:#{fieldname})
|
155
|
+
else
|
156
|
+
return nil
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
end_eval
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
165
|
+
|
166
|
+
end
|
167
|
+
##################################################################
|
168
|
+
##################################################################
|
169
|
+
|
170
|
+
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
# no rakefile yet
|