pk-merb_facebooker 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
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,52 @@
1
+ require 'rubygems'
2
+ require 'rake/gempackagetask'
3
+
4
+ NAME = "merb_facebooker"
5
+ VERSION = "0.0.3"
6
+ AUTHOR = "Chris Van Pelt"
7
+ EMAIL = "vanpelt@doloreslabs.com"
8
+ HOMEPAGE = "http://merb-plugins.rubyforge.org/merb_facebooker/"
9
+ SUMMARY = "Merb plugin that makes facebooker work with merb..."
10
+
11
+ spec = Gem::Specification.new do |s|
12
+ s.name = NAME
13
+ s.version = VERSION
14
+ s.platform = Gem::Platform::RUBY
15
+ s.has_rdoc = true
16
+ s.extra_rdoc_files = ["README", "LICENSE", 'TODO']
17
+ s.summary = SUMMARY
18
+ s.description = s.summary
19
+ s.author = AUTHOR
20
+ s.email = EMAIL
21
+ s.homepage = HOMEPAGE
22
+ s.add_dependency('merb-helpers', '>= 1.1')
23
+ s.add_dependency('facebooker', '>= 1.0.50')
24
+ s.require_path = 'lib'
25
+ s.files = %w(LICENSE README Rakefile TODO) + Dir.glob("{lib,specs}/**/*")
26
+ s.required_rubygems_version = ">= 1.3.5"
27
+ end
28
+
29
+ Rake::GemPackageTask.new(spec) do |pkg|
30
+ pkg.gem_spec = spec
31
+ end
32
+
33
+ desc "Create a gemspec file"
34
+ task :gemspec do
35
+ File.open("#{NAME}.gemspec", "w") do |file|
36
+ file.puts spec.to_ruby
37
+ end
38
+ end
39
+
40
+ desc "Installs gem"
41
+ task :install => [:package] do
42
+ sh %{sudo gem install pkg/#{NAME}-#{VERSION}}
43
+ end
44
+
45
+ namespace :jruby do
46
+
47
+ desc "Run :package and install the resulting .gem with jruby"
48
+ task :install => :package do
49
+ sh %{#{SUDO} jruby -S gem install pkg/#{NAME}-#{Merb::VERSION}.gem --no-rdoc --no-ri}
50
+ end
51
+
52
+ end
data/TODO ADDED
@@ -0,0 +1,5 @@
1
+ TODO:
2
+ Fix LICENSE with your name
3
+ Fix Rakefile with your name and contact info
4
+ Add your code to lib/merb_facebooker.rb
5
+ Add your Merb rake tasks to lib/merb_facebooker/merbtasks.rb
@@ -0,0 +1,228 @@
1
+ module Facebooker
2
+ module Merb
3
+ module Controller
4
+
5
+ def self.included(controller)
6
+ controller.extend(ClassMethods)
7
+ controller.before :set_fbml_format
8
+ end
9
+
10
+ #
11
+ # Just returns the @facebook_session instance variable
12
+ #
13
+ def facebook_session
14
+ @facebook_session
15
+ end
16
+
17
+ #
18
+ # Tries to secure the facebook_session, if it is not secured already, it tries to secure it
19
+ # via the request parameter 'auth_token', if that doesn't work, it tries to use the parameters
20
+ # from facebook (this could be in the request or via cookies [cookies in case of FBConnect]).
21
+ #
22
+ def set_facebook_session
23
+ session_set = session_already_secured? || secure_with_token! || secure_with_facebook_params!
24
+ if session_set
25
+ capture_facebook_friends_if_available!
26
+ Session.current = facebook_session
27
+ end
28
+ session_set
29
+ end
30
+
31
+ #
32
+ # initializes the @facebook_params instance using the method verified_facebook_params
33
+ #
34
+ def facebook_params
35
+ @facebook_params ||= verified_facebook_params
36
+ end
37
+
38
+ private
39
+
40
+ #
41
+ # Ensures there is an existing facebook session, and if so, it ask if it is secured.
42
+ #
43
+ def session_already_secured?
44
+ (@facebook_session = session[:facebook_session]) && session[:facebook_session].secured?
45
+ end
46
+
47
+ #
48
+ # Use auth_token parameter for the creation of a facebook_session
49
+ #
50
+ def secure_with_token!
51
+ if params['auth_token']
52
+ @facebook_session = new_facebook_session
53
+ @facebook_session.auth_token = params['auth_token']
54
+ @facebook_session.secure!
55
+ session[:facebook_session] = @facebook_session
56
+ end
57
+ end
58
+
59
+ #
60
+ # If the request is made from a facebook canvas, then it checks for the session key and the user
61
+ # from the facebook_params hash key
62
+ #
63
+ def secure_with_facebook_params!
64
+ debugger
65
+ return if !request_is_for_a_facebook_canvas? && !using_facebook_connect?
66
+
67
+ if ['user', 'session_key'].all? {|element| facebook_params[element]}
68
+ @facebook_session = new_facebook_session
69
+ @facebook_session.secure_with!(facebook_params['session_key'], facebook_params['user'], facebook_params['expires'])
70
+ session[:facebook_session] = @facebook_session
71
+ end
72
+ end
73
+
74
+ #
75
+ # Resets the facebook_session
76
+ #
77
+ def create_new_facebook_session_and_redirect!
78
+ session[:facebook_session] = new_facebook_session
79
+ throw :halt, redirect(session[:facebook_session].login_url) unless @installation_required
80
+ end
81
+
82
+ #
83
+ # Facebooker Session Factory
84
+ #
85
+ def new_facebook_session
86
+ Facebooker::Session.create(Facebooker::Session.api_key, Facebooker::Session.secret_key)
87
+ end
88
+
89
+ def capture_facebook_friends_if_available!
90
+ return unless request_is_for_a_facebook_canvas?
91
+ if friends = facebook_params['friends']
92
+ facebook_session.user.friends = friends.map do |friend_uid|
93
+ User.new(friend_uid, facebook_session)
94
+ end
95
+ end
96
+ end
97
+
98
+ #
99
+ # Helper method (acts as ActiveSupport's blank? method)
100
+ #
101
+ def blank?(value)
102
+ (value == '0' || value.nil? || value == '')
103
+ end
104
+
105
+ #
106
+ # Get all the parameters from facebook via the request or cookies...
107
+ # (Cookies have more presedence)
108
+ #
109
+ def verified_facebook_params
110
+ if !request.cookies[Facebooker::Session.api_key].blank?
111
+ facebook_sig_params = request.cookies.inject({}) do |collection, pair|
112
+ if pair.first =~ /^#{Facebooker::Session.api_key}_(.+)/
113
+ collection[$1] = pair.last
114
+ end
115
+ collection
116
+ end
117
+ else
118
+ # same ol...
119
+ facebook_sig_params = params.inject({}) do |collection, pair|
120
+ collection[pair.first.sub(/^fb_sig_/, '')] = pair.last if pair.first[0,7] == 'fb_sig_'
121
+ collection
122
+ end
123
+ verify_signature(facebook_sig_params, params['fb_sig'])
124
+ end
125
+
126
+ facebook_sig_params.inject(Mash.new) do |collection, pair|
127
+ collection[pair.first] = facebook_parameter_conversions[pair.first].call(pair.last)
128
+ collection
129
+ end
130
+ end
131
+
132
+ #
133
+ # Session timeout value
134
+ #
135
+ def earliest_valid_session
136
+ 48.hours.ago
137
+ end
138
+
139
+
140
+ #
141
+ # Checks if the signature matches the hash made from the parameters (does not apply on FBConnect)
142
+ #
143
+ def verify_signature(facebook_sig_params,expected_signature)
144
+ raw_string = facebook_sig_params.map{ |*args| args.join('=') }.sort.join
145
+ actual_sig = Digest::MD5.hexdigest([raw_string, Facebooker::Session.secret_key].join)
146
+ raise Facebooker::Session::IncorrectSignature if actual_sig != expected_signature
147
+ raise Facebooker::Session::SignatureTooOld if Time.at(facebook_sig_params['time'].to_f) < earliest_valid_session
148
+ true
149
+ end
150
+
151
+ #
152
+ # Parses the values from facebook_parameters
153
+ #
154
+ def facebook_parameter_conversions
155
+ @facebook_parameter_conversions ||= Hash.new do |hash, key|
156
+ lambda{|value| value}
157
+ end.merge(
158
+ 'time' => lambda{|value| Time.at(value.to_f)},
159
+ 'in_canvas' => lambda{|value| !blank?(value)},
160
+ 'added' => lambda{|value| !blank?(value)},
161
+ 'expires' => lambda{|value| blank?(value) ? nil : Time.at(value.to_f)},
162
+ 'friends' => lambda{|value| value.split(/,/)}
163
+ )
164
+ end
165
+
166
+ #
167
+ # Overwrite of the redirect method, if it is to a canvas, then use an fbml_redirect_tag
168
+ #
169
+ def redirect(*args)
170
+ if request_is_for_a_facebook_canvas?
171
+ fbml_redirect_tag(*args)
172
+ else
173
+ super
174
+ end
175
+ end
176
+
177
+ def fbml_redirect_tag(url)
178
+ puts url
179
+ "<fb:redirect url=\"#{url}\" />"
180
+ end
181
+
182
+ def request_is_for_a_facebook_canvas?
183
+ !params['fb_sig_in_canvas'].blank?
184
+ end
185
+
186
+ def using_facebook_connect?
187
+ !cookies[Facebooker::Session.api_key].blank?
188
+ end
189
+
190
+ def application_is_installed?
191
+ facebook_params['added']
192
+ end
193
+
194
+ def ensure_authenticated_to_facebook
195
+ set_facebook_session || create_new_facebook_session_and_redirect!
196
+ end
197
+
198
+ def ensure_application_is_installed_by_facebook_user
199
+ @installation_required = true
200
+ authenticated_and_installed = ensure_authenticated_to_facebook && application_is_installed?
201
+ application_is_not_installed_by_facebook_user unless authenticated_and_installed
202
+ authenticated_and_installed
203
+ end
204
+
205
+ def application_is_not_installed_by_facebook_user
206
+ throw :halt, redirect(session[:facebook_session].install_url)
207
+ end
208
+
209
+ def set_fbml_format
210
+ params[:format] = "fbml" if request_is_for_a_facebook_canvas?
211
+ end
212
+
213
+ module ClassMethods
214
+ #
215
+ # Creates a filter which reqires a user to have already authenticated to
216
+ # Facebook before executing actions. Accepts the same optional options hash which
217
+ # before_filter and after_filter accept.
218
+ def ensure_authenticated_to_facebook(options = {})
219
+ before :ensure_authenticated_to_facebook, options
220
+ end
221
+
222
+ def ensure_application_is_installed_by_facebook_user(options = {})
223
+ before :ensure_application_is_installed_by_facebook_user, options
224
+ end
225
+ end
226
+ end
227
+ end
228
+ 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,50 @@
1
+ namespace :facebooker do
2
+
3
+ desc "Create a basic facebooker.yml configuration file"
4
+ task :setup do
5
+ facebook_config = File.join(Merb.root,"config","facebooker.yml")
6
+ unless File.exist?(facebook_config)
7
+ cp File.dirname(__FILE__) + '/../../templates/config/facebooker.yml', facebook_config
8
+ puts "Configuration created in #{Merb.root}/config/facebooker.yml"
9
+ else
10
+ puts "#{Merb.root}/config/facebooker.yml already exists"
11
+ end
12
+ end
13
+
14
+ namespace :tunnel do
15
+ # Courtesy of Christopher Haupt
16
+ # http://www.BuildingWebApps.com
17
+ # http://www.LearningRails.com
18
+ desc "Create a reverse ssh tunnel from a public server to a private development server."
19
+ task :start => [ :config ] do
20
+ puts "Starting tunnel #{@public_host}:#{@public_port} to 0.0.0.0:#{@local_port}"
21
+ exec "ssh -nNT -g -R *:#{@public_port}:0.0.0.0:#{@local_port} #{@public_host_username}@#{@public_host}"
22
+ end
23
+
24
+ desc "Create a reverse ssh tunnel in the background. Requires ssh keys to be setup."
25
+ task :background_start => [ :config ] do
26
+ puts "Starting tunnel #{@public_host}:#{@public_port} to 0.0.0.0:#{@local_port}"
27
+ exec "ssh -nNT -g -R *:#{@public_port}:0.0.0.0:#{@local_port} #{@public_host_username}@#{@public_host} > /dev/null 2>&1 &"
28
+ end
29
+
30
+ # Adapted from Evan Weaver: http://blog.evanweaver.com/articles/2007/07/13/developing-a-facebook-app-locally/
31
+ desc "Check if reverse tunnel is running"
32
+ task :status => [ :config ] do
33
+ if `ssh #{@public_host} -l #{@public_host_username} netstat -an |
34
+ egrep "tcp.*:#{@public_port}.*LISTEN" | wc`.to_i > 0
35
+ puts "Seems ok"
36
+ else
37
+ puts "Down"
38
+ end
39
+ end
40
+
41
+ task :config do
42
+ facebook_config = File.join(Merb.root,"config","facebooker.yml")
43
+ FACEBOOKER = YAML.load_file(facebook_config)[Merb.environment]
44
+ @public_host_username = FACEBOOKER['tunnel']['public_host_username']
45
+ @public_host = FACEBOOKER['tunnel']['public_host']
46
+ @public_port = FACEBOOKER['tunnel']['public_port']
47
+ @local_port = FACEBOOKER['tunnel']['local_port']
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,33 @@
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
+
7
+ # Merb gives you a Merb::Plugins.config hash...feel free to put your stuff in your piece of it
8
+ facebook_config = "#{Merb.root}/config/facebooker.yml"
9
+ if File.exist?(facebook_config)
10
+ Merb::Plugins.config[:merb_facebooker] = YAML.load_file(facebook_config)[Merb.environment]
11
+ ENV['FACEBOOK_API_KEY'] = Merb::Plugins.config[:merb_facebooker]['api_key']
12
+ ENV['FACEBOOK_SECRET_KEY'] = Merb::Plugins.config[:merb_facebooker]['secret_key']
13
+ ENV['FACEBOOKER_RELATIVE_URL_ROOT'] = Merb::Plugins.config[:merb_facebooker]['canvas_page_name']
14
+ #ActionController::Base.asset_host = FACEBOOKER['callback_url']
15
+ end
16
+
17
+ Merb.add_mime_type(:fbml, :to_fbml, %w[application/fbml text/fbml], :encoding => "UTF-8")
18
+ Merb::Request.http_method_overrides.push(
19
+ proc { |c| c.params[:fb_sig_request_method].clone if c.params[:fb_sig_request_method]}
20
+ )
21
+
22
+ Merb::BootLoader.before_app_loads do
23
+ Merb::Controller.send(:include, Facebooker::Merb::Controller)
24
+ Merb::Controller.send(:include, Facebooker::Merb::Helpers)
25
+ # require code that must be loaded before the application
26
+ end
27
+
28
+ Merb::BootLoader.after_app_loads do
29
+ # code that can be required after the application loads
30
+ end
31
+
32
+ Merb::Plugins.add_rakefiles "merb_facebooker/merbtasks"
33
+ end
metadata ADDED
@@ -0,0 +1,83 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pk-merb_facebooker
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ platform: ruby
6
+ authors:
7
+ - Chris Van Pelt
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-09-14 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: merb-helpers
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "1.1"
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: 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.50
34
+ version:
35
+ description: Merb plugin that makes facebooker 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
51
+ - lib/merb_facebooker/controller.rb
52
+ - lib/merb_facebooker/helpers.rb
53
+ - lib/merb_facebooker/merbtasks.rb
54
+ - lib/merb_facebooker.rb
55
+ has_rdoc: false
56
+ homepage: http://merb-plugins.rubyforge.org/merb_facebooker/
57
+ licenses:
58
+ post_install_message:
59
+ rdoc_options: []
60
+
61
+ require_paths:
62
+ - lib
63
+ required_ruby_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: "0"
68
+ version:
69
+ required_rubygems_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: 1.3.5
74
+ version:
75
+ requirements: []
76
+
77
+ rubyforge_project:
78
+ rubygems_version: 1.3.5
79
+ signing_key:
80
+ specification_version: 3
81
+ summary: Merb plugin that makes facebooker work with merb...
82
+ test_files: []
83
+