rpbertp13-merb_facebooker 0.0.2.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/LICENSE +20 -0
- data/README +15 -0
- data/Rakefile +45 -0
- data/TODO +5 -0
- data/lib/merb_facebooker.rb +35 -0
- data/lib/merb_facebooker/controller.rb +259 -0
- data/lib/merb_facebooker/helpers.rb +111 -0
- data/lib/merb_facebooker/merbtasks.rb +49 -0
- data/spec/merb_facebooker_spec.rb +63 -0
- data/spec/spec_helper.rb +16 -0
- data/templates/config/facebooker.yml +41 -0
- metadata +84 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2008 YOUR NAME
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
merb_facebooker
|
2
|
+
===============
|
3
|
+
|
4
|
+
A plugin for Merb that hooks up the facebooker gem. Currently it just mixes some good stuff into Merb::Controller... the helpers are missing along with the CGI extentions. These should be easily ported from the rails plugin portion of facebooker... I just haven't needed it yet.
|
5
|
+
|
6
|
+
Finnaly facebook comes to Merb :)
|
7
|
+
|
8
|
+
Installation
|
9
|
+
==============
|
10
|
+
|
11
|
+
git clone git://github.com/vanpelt/merb_facebooker.git
|
12
|
+
cd merb_facebooker
|
13
|
+
rake gem
|
14
|
+
cd ../your_merb_app
|
15
|
+
gem install -i gems ../merb_facebooker/pkg/merb_facebooker-*.gem
|
data/Rakefile
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake/gempackagetask'
|
3
|
+
|
4
|
+
PLUGIN = "merb_facebooker"
|
5
|
+
NAME = "merb_facebooker"
|
6
|
+
VERSION = "0.0.2"
|
7
|
+
AUTHOR = "Chris Van Pelt"
|
8
|
+
EMAIL = "vanpelt@doloreslabs.com"
|
9
|
+
HOMEPAGE = "http://merb-plugins.rubyforge.org/merb_facebooker/"
|
10
|
+
SUMMARY = "Merb plugin that makes rfacebooker work with merb..."
|
11
|
+
|
12
|
+
spec = Gem::Specification.new do |s|
|
13
|
+
s.name = NAME
|
14
|
+
s.version = VERSION
|
15
|
+
s.platform = Gem::Platform::RUBY
|
16
|
+
s.has_rdoc = true
|
17
|
+
s.extra_rdoc_files = ["README", "LICENSE", 'TODO']
|
18
|
+
s.summary = SUMMARY
|
19
|
+
s.description = s.summary
|
20
|
+
s.author = AUTHOR
|
21
|
+
s.email = EMAIL
|
22
|
+
s.homepage = HOMEPAGE
|
23
|
+
s.add_dependency('merb-core', '>= 0.9.4')
|
24
|
+
s.add_dependency('facebooker')
|
25
|
+
s.require_path = 'lib'
|
26
|
+
s.autorequire = PLUGIN
|
27
|
+
s.files = %w(LICENSE README Rakefile TODO) + Dir.glob("{lib,specs}/**/*")
|
28
|
+
end
|
29
|
+
|
30
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
31
|
+
pkg.gem_spec = spec
|
32
|
+
end
|
33
|
+
|
34
|
+
task :install => [:package] do
|
35
|
+
sh %{sudo gem install pkg/#{NAME}-#{VERSION}}
|
36
|
+
end
|
37
|
+
|
38
|
+
namespace :jruby do
|
39
|
+
|
40
|
+
desc "Run :package and install the resulting .gem with jruby"
|
41
|
+
task :install => :package do
|
42
|
+
sh %{#{SUDO} jruby -S gem install pkg/#{NAME}-#{Merb::VERSION}.gem --no-rdoc --no-ri}
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
data/TODO
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
#make sure we're running inside Merb
|
2
|
+
require 'merb_facebooker/controller'
|
3
|
+
require 'merb_facebooker/helpers'
|
4
|
+
|
5
|
+
if defined?(Merb::Plugins)
|
6
|
+
dependency "facebooker"
|
7
|
+
dependency "merb-helpers"
|
8
|
+
|
9
|
+
# Merb gives you a Merb::Plugins.config hash...feel free to put your stuff in your piece of it
|
10
|
+
facebook_config = "#{Merb.root}/config/facebooker.yml"
|
11
|
+
if File.exist?(facebook_config)
|
12
|
+
Merb::Plugins.config[:merb_facebooker] = YAML.load_file(facebook_config)[Merb.environment]
|
13
|
+
ENV['FACEBOOK_API_KEY'] = Merb::Plugins.config[:merb_facebooker]['api_key']
|
14
|
+
ENV['FACEBOOK_SECRET_KEY'] = Merb::Plugins.config[:merb_facebooker]['secret_key']
|
15
|
+
ENV['FACEBOOKER_RELATIVE_URL_ROOT'] = Merb::Plugins.config[:merb_facebooker]['canvas_page_name']
|
16
|
+
#ActionController::Base.asset_host = FACEBOOKER['callback_url']
|
17
|
+
end
|
18
|
+
|
19
|
+
Merb.add_mime_type(:fbml, :to_fbml, %w[application/fbml text/fbml], :Encoding => "UTF-8")
|
20
|
+
Merb::Request.http_method_overrides.push(
|
21
|
+
proc { |c| c.params[:fb_sig_request_method] }
|
22
|
+
)
|
23
|
+
|
24
|
+
Merb::BootLoader.before_app_loads do
|
25
|
+
Merb::Controller.send(:include, Facebooker::Merb::Controller)
|
26
|
+
Merb::Controller.send(:include, Facebooker::Merb::Helpers)
|
27
|
+
# require code that must be loaded before the application
|
28
|
+
end
|
29
|
+
|
30
|
+
Merb::BootLoader.after_app_loads do
|
31
|
+
# code that can be required after the application loads
|
32
|
+
end
|
33
|
+
|
34
|
+
Merb::Plugins.add_rakefiles "merb_facebooker/merbtasks"
|
35
|
+
end
|
@@ -0,0 +1,259 @@
|
|
1
|
+
module Facebooker
|
2
|
+
module Merb
|
3
|
+
module Controller
|
4
|
+
def self.included(controller)
|
5
|
+
controller.extend(ClassMethods)
|
6
|
+
controller.before :set_fbml_format
|
7
|
+
end
|
8
|
+
|
9
|
+
def absolute_url(*args)
|
10
|
+
options = extract_options_from_args!(args) || {}
|
11
|
+
options[:protocol] ||= request.protocol
|
12
|
+
options[:host] = Facebooker.canvas_server_base + Facebooker.facebook_path_prefix
|
13
|
+
args << options
|
14
|
+
super(*args)
|
15
|
+
end
|
16
|
+
|
17
|
+
#
|
18
|
+
# Just returns the @facebook_session instance variable
|
19
|
+
#
|
20
|
+
def facebook_session
|
21
|
+
@facebook_session
|
22
|
+
end
|
23
|
+
|
24
|
+
#
|
25
|
+
# Tries to secure the facebook_session, if it is not secured already, it tries to secure it
|
26
|
+
# via the request parameter 'auth_token', if that doesn't work, it tries to use the parameters
|
27
|
+
# from facebook (this could be in the request or via cookies [cookies in case of FBConnect]).
|
28
|
+
#
|
29
|
+
def set_facebook_session
|
30
|
+
session_set = session_already_secured? || secure_with_token! || secure_with_facebook_params!
|
31
|
+
if session_set
|
32
|
+
capture_facebook_friends_if_available!
|
33
|
+
Session.current = facebook_session
|
34
|
+
end
|
35
|
+
session_set
|
36
|
+
end
|
37
|
+
|
38
|
+
#
|
39
|
+
# initializes the @facebook_params instance using the method verified_facebook_params
|
40
|
+
#
|
41
|
+
def facebook_params
|
42
|
+
@facebook_params ||= verified_facebook_params
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
#
|
48
|
+
# Ensures there is an existing facebook session, and if so, it ask if it is secured.
|
49
|
+
#
|
50
|
+
def session_already_secured?
|
51
|
+
(@facebook_session = session[:facebook_session]) && session[:facebook_session].secured?
|
52
|
+
end
|
53
|
+
|
54
|
+
#
|
55
|
+
# Use auth_token parameter for the creation of a facebook_session
|
56
|
+
#
|
57
|
+
def secure_with_token!
|
58
|
+
if params['auth_token']
|
59
|
+
@facebook_session = new_facebook_session
|
60
|
+
@facebook_session.auth_token = params['auth_token']
|
61
|
+
@facebook_session.secure!
|
62
|
+
session[:facebook_session] = @facebook_session
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
#
|
67
|
+
# If the request is made from a facebook canvas, then it checks for the session key and the user
|
68
|
+
# from the facebook_params hash key
|
69
|
+
#
|
70
|
+
def secure_with_facebook_params!
|
71
|
+
debugger
|
72
|
+
return if !request_is_for_a_facebook_canvas? && !using_facebook_connect?
|
73
|
+
|
74
|
+
if ['user', 'session_key'].all? {|element| facebook_params[element]}
|
75
|
+
@facebook_session = new_facebook_session
|
76
|
+
@facebook_session.secure_with!(facebook_params['session_key'], facebook_params['user'], facebook_params['expires'])
|
77
|
+
session[:facebook_session] = @facebook_session
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
#
|
82
|
+
# Resets the facebook_session
|
83
|
+
#
|
84
|
+
def create_new_facebook_session_and_redirect!
|
85
|
+
session[:facebook_session] = new_facebook_session
|
86
|
+
throw :halt, redirect(session[:facebook_session].login_url) unless @installation_required
|
87
|
+
end
|
88
|
+
|
89
|
+
#
|
90
|
+
# Facebooker Session Factory
|
91
|
+
#
|
92
|
+
def new_facebook_session
|
93
|
+
Facebooker::Session.create(Facebooker::Session.api_key, Facebooker::Session.secret_key)
|
94
|
+
end
|
95
|
+
|
96
|
+
def capture_facebook_friends_if_available!
|
97
|
+
return unless request_is_for_a_facebook_canvas?
|
98
|
+
if friends = facebook_params['friends']
|
99
|
+
facebook_session.user.friends = friends.map do |friend_uid|
|
100
|
+
User.new(friend_uid, facebook_session)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
#
|
106
|
+
# Helper method (acts as ActiveSupport's blank? method)
|
107
|
+
#
|
108
|
+
def blank?(value)
|
109
|
+
(value == '0' || value.nil? || value == '')
|
110
|
+
end
|
111
|
+
|
112
|
+
#
|
113
|
+
# Get all the parameters from facebook via the request or cookies...
|
114
|
+
# (Cookies have more presedence)
|
115
|
+
#
|
116
|
+
def verified_facebook_params
|
117
|
+
if !request.cookies[Facebooker::Session.api_key].blank?
|
118
|
+
facebook_sig_params = request.cookies.inject({}) do |collection, pair|
|
119
|
+
if pair.first =~ /^#{Facebooker::Session.api_key}_(.+)/
|
120
|
+
collection[$1] = pair.last
|
121
|
+
end
|
122
|
+
collection
|
123
|
+
end
|
124
|
+
else
|
125
|
+
# same ol...
|
126
|
+
facebook_sig_params = params.inject({}) do |collection, pair|
|
127
|
+
collection[pair.first.sub(/^fb_sig_/, '')] = pair.last if pair.first[0,7] == 'fb_sig_'
|
128
|
+
collection
|
129
|
+
end
|
130
|
+
verify_signature(facebook_sig_params, params['fb_sig'])
|
131
|
+
end
|
132
|
+
|
133
|
+
facebook_sig_params.inject(Mash.new) do |collection, pair|
|
134
|
+
collection[pair.first] = facebook_parameter_conversions[pair.first].call(pair.last)
|
135
|
+
collection
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
#
|
140
|
+
# Session timeout value
|
141
|
+
#
|
142
|
+
def earliest_valid_session
|
143
|
+
48.hours.ago
|
144
|
+
end
|
145
|
+
|
146
|
+
|
147
|
+
#
|
148
|
+
# Checks if the signature matches the hash made from the parameters (does not apply on FBConnect)
|
149
|
+
#
|
150
|
+
def verify_signature(facebook_sig_params,expected_signature)
|
151
|
+
raw_string = facebook_sig_params.map{ |*args| args.join('=') }.sort.join
|
152
|
+
actual_sig = Digest::MD5.hexdigest([raw_string, Facebooker::Session.secret_key].join)
|
153
|
+
raise Facebooker::Session::IncorrectSignature if actual_sig != expected_signature
|
154
|
+
raise Facebooker::Session::SignatureTooOld if Time.at(facebook_sig_params['time'].to_f) < earliest_valid_session
|
155
|
+
true
|
156
|
+
end
|
157
|
+
|
158
|
+
#
|
159
|
+
# Parses the values from facebook_parameters
|
160
|
+
#
|
161
|
+
def facebook_parameter_conversions
|
162
|
+
@facebook_parameter_conversions ||= Hash.new do |hash, key|
|
163
|
+
lambda{|value| value}
|
164
|
+
end.merge(
|
165
|
+
'time' => lambda{|value| Time.at(value.to_f)},
|
166
|
+
'in_canvas' => lambda{|value| !blank?(value)},
|
167
|
+
'added' => lambda{|value| !blank?(value)},
|
168
|
+
'expires' => lambda{|value| blank?(value) ? nil : Time.at(value.to_f)},
|
169
|
+
'friends' => lambda{|value| value.split(/,/)}
|
170
|
+
)
|
171
|
+
end
|
172
|
+
|
173
|
+
#
|
174
|
+
# Overwrite of the redirect method, if it is to a canvas, then use an fbml_redirect_tag
|
175
|
+
#
|
176
|
+
def redirect(*args)
|
177
|
+
if request_is_for_a_facebook_canvas?
|
178
|
+
fbml_redirect_tag(*args)
|
179
|
+
else
|
180
|
+
super
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
def fbml_redirect_tag(url)
|
185
|
+
puts url
|
186
|
+
"<fb:redirect url=\"#{url}\" />"
|
187
|
+
end
|
188
|
+
|
189
|
+
def request_is_for_a_facebook_canvas?
|
190
|
+
!params['fb_sig_in_canvas'].blank?
|
191
|
+
end
|
192
|
+
|
193
|
+
def using_facebook_connect?
|
194
|
+
!cookies[Facebooker::Session.api_key].blank?
|
195
|
+
end
|
196
|
+
|
197
|
+
def application_is_installed?
|
198
|
+
facebook_params['added']
|
199
|
+
end
|
200
|
+
|
201
|
+
def ensure_has_status_update(options = {})
|
202
|
+
has_extended_permission?("status_update") || application_needs_permission("status_update", options)
|
203
|
+
end
|
204
|
+
|
205
|
+
def ensure_has_photo_upload(options = {})
|
206
|
+
has_extended_permission?("photo_upload") || application_needs_permission("photo_upload", options)
|
207
|
+
end
|
208
|
+
|
209
|
+
def ensure_has_create_listing(options = {})
|
210
|
+
has_extended_permission?("create_listing") || application_needs_permission("create_listing", options)
|
211
|
+
end
|
212
|
+
|
213
|
+
def ensure_has_rsvp_event(options = {})
|
214
|
+
has_extended_permission?("rsvp_event") || application_needs_permission("rsvp_event", options)
|
215
|
+
end
|
216
|
+
|
217
|
+
def application_needs_permission(perm, options = {})
|
218
|
+
throw :halt, redirect(facebook_session.permission_url(perm, options))
|
219
|
+
end
|
220
|
+
|
221
|
+
def has_extended_permission?(perm)
|
222
|
+
params["fb_sig_ext_perms"] and params["fb_sig_ext_perms"].include?(perm)
|
223
|
+
end
|
224
|
+
|
225
|
+
def ensure_authenticated_to_facebook
|
226
|
+
set_facebook_session || create_new_facebook_session_and_redirect!
|
227
|
+
end
|
228
|
+
|
229
|
+
def ensure_application_is_installed_by_facebook_user
|
230
|
+
@installation_required = true
|
231
|
+
authenticated_and_installed = ensure_authenticated_to_facebook && application_is_installed?
|
232
|
+
application_is_not_installed_by_facebook_user unless authenticated_and_installed
|
233
|
+
authenticated_and_installed
|
234
|
+
end
|
235
|
+
|
236
|
+
def application_is_not_installed_by_facebook_user
|
237
|
+
throw :halt, redirect(session[:facebook_session].install_url)
|
238
|
+
end
|
239
|
+
|
240
|
+
def set_fbml_format
|
241
|
+
params[:format] = "fbml" if request_is_for_a_facebook_canvas?
|
242
|
+
end
|
243
|
+
|
244
|
+
module ClassMethods
|
245
|
+
#
|
246
|
+
# Creates a filter which reqires a user to have already authenticated to
|
247
|
+
# Facebook before executing actions. Accepts the same optional options hash which
|
248
|
+
# before_filter and after_filter accept.
|
249
|
+
def ensure_authenticated_to_facebook(options = {})
|
250
|
+
before :ensure_authenticated_to_facebook, options
|
251
|
+
end
|
252
|
+
|
253
|
+
def ensure_application_is_installed_by_facebook_user(options = {})
|
254
|
+
before :ensure_application_is_installed_by_facebook_user, options
|
255
|
+
end
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
module Facebooker
|
2
|
+
module Merb
|
3
|
+
module Helpers
|
4
|
+
#const
|
5
|
+
VALID_FB_SHARED_PHOTO_SIZES = [:thumb, :small, :normal, :square]
|
6
|
+
VALID_FB_PHOTO_SIZES = VALID_FB_SHARED_PHOTO_SIZES
|
7
|
+
VALID_FB_PROFILE_PIC_SIZES = VALID_FB_SHARED_PHOTO_SIZES
|
8
|
+
|
9
|
+
VALID_FB_SHARED_ALIGN_VALUES = [:left, :right]
|
10
|
+
VALID_FB_PHOTO_ALIGN_VALUES = VALID_FB_SHARED_ALIGN_VALUES
|
11
|
+
VALID_FB_TAB_ITEM_ALIGN_VALUES = VALID_FB_SHARED_ALIGN_VALUES
|
12
|
+
|
13
|
+
FB_PHOTO_VALID_OPTION_KEYS = [:uid, :size, :align]
|
14
|
+
|
15
|
+
# Create an fb:request-form without a selector
|
16
|
+
#
|
17
|
+
# The block passed to this tag is used as the content of the form
|
18
|
+
#
|
19
|
+
# The message param is the name sent to content_for that specifies the body of the message
|
20
|
+
#
|
21
|
+
# For example,
|
22
|
+
#
|
23
|
+
# <% content_for("invite_message") do %>
|
24
|
+
# This gets sent in the invite. <%= fb_req_choice("with a button!",new_poke_path) %>
|
25
|
+
# <% end %>
|
26
|
+
# <% fb_request_form("Poke","invite_message",create_poke_path) do %>
|
27
|
+
# Send a poke to: <%= fb_friend_selector %> <br />
|
28
|
+
# <%= fb_request_form_submit %>
|
29
|
+
# <% end %>
|
30
|
+
|
31
|
+
def fb_request_form(type ,message_param,url,&block)
|
32
|
+
content = capture(&block)
|
33
|
+
message = @_caught_content[message_param]
|
34
|
+
concat(tag("fb:request-form", content,
|
35
|
+
{:action=>url,:method=>"post",:invite=>true,:type=>type,:content=>message}),
|
36
|
+
block.binding)
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
# Provides a FBML fb_profile_pic tag with the provided uid
|
41
|
+
# ==== Parameters
|
42
|
+
# user<OrmObject>:: The user object
|
43
|
+
# options<Hash>:: specify the users picture size
|
44
|
+
#
|
45
|
+
# === Options (options)
|
46
|
+
# :size<Symbol>:: The size of the profile picture :small, :normal and :square
|
47
|
+
#
|
48
|
+
# ==== Returns
|
49
|
+
# String:: The fbml tag defaulting with thumb picture
|
50
|
+
#
|
51
|
+
# ==== Example
|
52
|
+
# <%= fb_profile_pic(@user) %>
|
53
|
+
def fb_profile_pic(user, options = {})
|
54
|
+
validate_fb_profile_pic_size(options)
|
55
|
+
options.merge!(:uid => cast_to_facebook_id(user))
|
56
|
+
self_closing_tag("fb:profile-pic", options)
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
|
61
|
+
# Provides a FBML fb_photo tag with the a facebook photo
|
62
|
+
# ==== Parameters
|
63
|
+
# photo<Facebooker::Photo>:: The photo object Or Objec that respond to photo_id
|
64
|
+
# options<Hash>:: specify the pic size and
|
65
|
+
#
|
66
|
+
# === Options (options)
|
67
|
+
# <em> See: </em> http://wiki.developers.facebook.com/index.php/Fb:photo for complete list of options
|
68
|
+
#
|
69
|
+
# ==== Returns
|
70
|
+
# String:: The fbml photo tag defaulting with thumb picture
|
71
|
+
#
|
72
|
+
# ==== Example
|
73
|
+
# <%= fb_profile_pic(@user) %>
|
74
|
+
def fb_photo(photo, options = {})
|
75
|
+
# options.assert_valid_keys(FB_PHOTO_VALID_OPTION_KEYS) # TODO asserts
|
76
|
+
options.merge!(:pid => cast_to_photo_id(photo))
|
77
|
+
validate_fb_photo_size(options)
|
78
|
+
validate_fb_photo_align_value(options)
|
79
|
+
self_closing_tag("fb:photo", options)
|
80
|
+
end
|
81
|
+
|
82
|
+
def cast_to_photo_id(object)
|
83
|
+
object.respond_to?(:photo_id) ? object.photo_id : object
|
84
|
+
end
|
85
|
+
|
86
|
+
protected
|
87
|
+
def validate_fb_photo_align_value(options)
|
88
|
+
if options.has_key?(:align) && !VALID_FB_PHOTO_ALIGN_VALUES.include?(options[:align].to_sym)
|
89
|
+
raise(ArgumentError, "Unkown value for align: #{options[:align]}")
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def cast_to_facebook_id(object)
|
94
|
+
Facebooker::User.cast_to_facebook_id(object)
|
95
|
+
end
|
96
|
+
|
97
|
+
def validate_fb_photo_size(options)
|
98
|
+
if options.has_key?(:size) && !VALID_FB_PHOTO_SIZES.include?(options[:size].to_sym)
|
99
|
+
raise(ArgumentError, "Unkown value for size: #{options[:size]}")
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def validate_fb_profile_pic_size(options)
|
104
|
+
if options.has_key?(:size) && !VALID_FB_PROFILE_PIC_SIZES.include?(options[:size].to_sym)
|
105
|
+
raise(ArgumentError, "Unkown value for size: #{options[:size]}")
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
end # Helpers
|
110
|
+
end # Merb
|
111
|
+
end # Facebooker
|
@@ -0,0 +1,49 @@
|
|
1
|
+
namespace :facebooker do
|
2
|
+
desc "Create a basic facebooker.yml configuration file"
|
3
|
+
task :setup do
|
4
|
+
facebook_config = File.join(Merb.root,"config","facebooker.yml")
|
5
|
+
unless File.exist?(facebook_config)
|
6
|
+
cp File.dirname(__FILE__) + '/../../templates/config/facebooker.yml', facebook_config
|
7
|
+
puts "Configuration created in #{Merb.root}/config/facebooker.yml"
|
8
|
+
else
|
9
|
+
puts "#{Merb.root}/config/facebooker.yml already exists"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
namespace :tunnel do
|
14
|
+
# Courtesy of Christopher Haupt
|
15
|
+
# http://www.BuildingWebApps.com
|
16
|
+
# http://www.LearningRails.com
|
17
|
+
desc "Create a reverse ssh tunnel from a public server to a private development server."
|
18
|
+
task :start => [ :config ] do
|
19
|
+
puts "Starting tunnel #{@public_host}:#{@public_port} to 0.0.0.0:#{@local_port}"
|
20
|
+
exec "ssh -nNT -g -R *:#{@public_port}:0.0.0.0:#{@local_port} #{@public_host_username}@#{@public_host}"
|
21
|
+
end
|
22
|
+
|
23
|
+
desc "Create a reverse ssh tunnel in the background. Requires ssh keys to be setup."
|
24
|
+
task :background_start => [ :config ] do
|
25
|
+
puts "Starting tunnel #{@public_host}:#{@public_port} to 0.0.0.0:#{@local_port}"
|
26
|
+
exec "ssh -nNT -g -R *:#{@public_port}:0.0.0.0:#{@local_port} #{@public_host_username}@#{@public_host} > /dev/null 2>&1 &"
|
27
|
+
end
|
28
|
+
|
29
|
+
# Adapted from Evan Weaver: http://blog.evanweaver.com/articles/2007/07/13/developing-a-facebook-app-locally/
|
30
|
+
desc "Check if reverse tunnel is running"
|
31
|
+
task :status => [ :config ] do
|
32
|
+
if `ssh #{@public_host} -l #{@public_host_username} netstat -an |
|
33
|
+
egrep "tcp.*:#{@public_port}.*LISTEN" | wc`.to_i > 0
|
34
|
+
puts "Seems ok"
|
35
|
+
else
|
36
|
+
puts "Down"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
task :config do
|
41
|
+
facebook_config = File.dirname(__FILE__) + '/../../../../../config/facebooker.yml'
|
42
|
+
FACEBOOKER = YAML.load_file(facebook_config)[Merb.environment]
|
43
|
+
@public_host_username = FACEBOOKER['tunnel']['public_host_username']
|
44
|
+
@public_host = FACEBOOKER['tunnel']['public_host']
|
45
|
+
@public_port = FACEBOOKER['tunnel']['public_port']
|
46
|
+
@local_port = FACEBOOKER['tunnel']['local_port']
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
Merb::Router.prepare do |r|
|
4
|
+
r.match('/').to(:controller => 'facebook_helpers', :action =>'index')
|
5
|
+
end
|
6
|
+
|
7
|
+
class FacebookerHelpers < Merb::Controller
|
8
|
+
def index
|
9
|
+
"hi"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
Merb::Config.use { |c|
|
14
|
+
c[:framework] = {},
|
15
|
+
c[:session_store] = 'none',
|
16
|
+
c[:exception_details] = true
|
17
|
+
}
|
18
|
+
|
19
|
+
# ok lets start with the helpers and go from there
|
20
|
+
describe "Controller With Facebooker Helpers" do
|
21
|
+
before(:all) do
|
22
|
+
@controller = FacebookerHelpers.new(fake_request)
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "calling fb_profile(@user, options) given user has facebook_id=1234" do
|
26
|
+
before(:all) do
|
27
|
+
@user = stub("User", :facebook_id => 1234)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should be able to call" do
|
31
|
+
@controller.should respond_to(:fb_profile_pic)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should equal <fb:profile-pic uid='1234' /> when calling with @user" do
|
35
|
+
@controller.fb_profile_pic(@user).should == "<fb:profile-pic uid=\"1234\"/>"
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should equal <fb:profile-pic uid='1234' size='small'/> when calling with @user, :size => :small" do
|
39
|
+
@controller.fb_profile_pic(@user, :size => :small).should == "<fb:profile-pic uid=\"1234\" size=\"small\"/>"
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should raise Argument Error is the incorrect size is given when calling @user, :size => :egg" do
|
43
|
+
lambda{@controller.fb_profile_pic(@user, :size => :egg)}.should raise_error
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
describe "calling fb_photo where given photo has an photo_id = 1234" do
|
49
|
+
before(:all) do
|
50
|
+
@photo = stub("Photo", :photo_id => 1234)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should be able to call" do
|
54
|
+
@controller.should respond_to(:fb_photo)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should equal <fb:photo pid=\"1234\" /> with parameter @photo" do
|
58
|
+
@photo.stub!(:photo_id).and_return(1234) # DONT ASK
|
59
|
+
@controller.fb_photo(@photo).should == "<fb:photo pid=\"1234\"/>"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
$TESTING=true
|
2
|
+
$:.push File.join(File.dirname(__FILE__), '..', 'lib')
|
3
|
+
|
4
|
+
# going to be specing for Merb so lets just do that shall we
|
5
|
+
require 'rubygems'
|
6
|
+
require 'merb-core'
|
7
|
+
require 'merb_facebooker'
|
8
|
+
require 'spec'
|
9
|
+
|
10
|
+
Merb.start_environment(:testing => true, :adapter => 'runner', :environment => ENV['MERB_ENV'] || 'test')
|
11
|
+
|
12
|
+
Spec::Runner.configure do |config|
|
13
|
+
config.include(Merb::Test::ViewHelper)
|
14
|
+
config.include(Merb::Test::RouteHelper)
|
15
|
+
config.include(Merb::Test::ControllerHelper)
|
16
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# The api key, secret key, and canvas page name are required to get started
|
2
|
+
# Tunnel configuration is only needed if you are going to use the facebooker:tunnel Rake tasks
|
3
|
+
# Your callback url in Facebook should be set to http://public_host:public_port
|
4
|
+
# To develop for the new profile design, add the following key..
|
5
|
+
# api: new
|
6
|
+
# remove the key or set it to anything else to use the old facebook design.
|
7
|
+
# This should only be necessary until the final version of the new profile is released.
|
8
|
+
|
9
|
+
development:
|
10
|
+
api_key:
|
11
|
+
secret_key:
|
12
|
+
canvas_page_name:
|
13
|
+
callback_url:
|
14
|
+
pretty_errors: true
|
15
|
+
tunnel:
|
16
|
+
public_host_username:
|
17
|
+
public_host:
|
18
|
+
public_port: 4007
|
19
|
+
local_port: 3000
|
20
|
+
|
21
|
+
test:
|
22
|
+
api_key:
|
23
|
+
secret_key:
|
24
|
+
canvas_page_name:
|
25
|
+
callback_url:
|
26
|
+
tunnel:
|
27
|
+
public_host_username:
|
28
|
+
public_host:
|
29
|
+
public_port: 4007
|
30
|
+
local_port: 3000
|
31
|
+
|
32
|
+
production:
|
33
|
+
api_key:
|
34
|
+
secret_key:
|
35
|
+
canvas_page_name:
|
36
|
+
callback_url:
|
37
|
+
tunnel:
|
38
|
+
public_host_username:
|
39
|
+
public_host:
|
40
|
+
public_port: 4007
|
41
|
+
local_port: 3000
|
metadata
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rpbertp13-merb_facebooker
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2.3
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Chris Van Pelt
|
8
|
+
autorequire: merb_facebooker
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-05-16 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: merb-core
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.9.4
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: mmangino-facebooker
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.0.10
|
34
|
+
version:
|
35
|
+
description: Merb plugin that makes rfacebooker work with merb...
|
36
|
+
email: vanpelt@doloreslabs.com
|
37
|
+
executables: []
|
38
|
+
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files:
|
42
|
+
- README
|
43
|
+
- LICENSE
|
44
|
+
- TODO
|
45
|
+
files:
|
46
|
+
- LICENSE
|
47
|
+
- README
|
48
|
+
- Rakefile
|
49
|
+
- TODO
|
50
|
+
- lib/merb_facebooker/controller.rb
|
51
|
+
- lib/merb_facebooker/helpers.rb
|
52
|
+
- lib/merb_facebooker/merbtasks.rb
|
53
|
+
- lib/merb_facebooker.rb
|
54
|
+
- spec/merb_facebooker_spec.rb
|
55
|
+
- spec/spec_helper.rb
|
56
|
+
- templates/config/facebooker.yml
|
57
|
+
has_rdoc: true
|
58
|
+
homepage: http://merb-plugins.rubyforge.org/merb_facebooker/
|
59
|
+
post_install_message:
|
60
|
+
rdoc_options: []
|
61
|
+
|
62
|
+
require_paths:
|
63
|
+
- lib
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: "0"
|
69
|
+
version:
|
70
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: "0"
|
75
|
+
version:
|
76
|
+
requirements: []
|
77
|
+
|
78
|
+
rubyforge_project:
|
79
|
+
rubygems_version: 1.2.0
|
80
|
+
signing_key:
|
81
|
+
specification_version: 2
|
82
|
+
summary: Merb plugin that makes rfacebooker work with merb...
|
83
|
+
test_files: []
|
84
|
+
|