Browse files

Convert Frankie into a gem to work with Sinatra 0.2.0

  • Loading branch information...
1 parent 47911c1 commit d53ba0cfc5ace5d9d1bce13435befd49a1fc05e6 Ron Evans committed Apr 12, 2008
Showing with 299 additions and 155 deletions.
  1. BIN .DS_Store
  2. +3 −0 .gitignore
  3. +1 −0 CHANGELOG
  4. +20 −0 LICENSE
  5. +7 −0 Manifest
  6. +69 −0 README.rdoc
  7. +29 −0 Rakefile
  8. +160 −155 lib/frankie.rb
  9. +6 −0 test/frankie_test.rb
  10. +4 −0 test/helper.rb
View
BIN .DS_Store
Binary file not shown.
View
3 .gitignore
@@ -0,0 +1,3 @@
+doc
+pkg
+*.log
View
1 CHANGELOG
@@ -0,0 +1 @@
+v0.2.0. Converted codebase to become Ruby Gem
View
20 LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2008 Ron Evans
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
View
7 Manifest
@@ -0,0 +1,7 @@
+CHANGELOG
+lib/frankie.rb
+LICENSE
+Manifest
+Rakefile
+README.rdoc
+test/frankie_test.rb
View
69 README.rdoc
@@ -0,0 +1,69 @@
+= Frankie
+
+Frankie (http://facethesinatra.com) is a plugin for the Sinatra web framework (http://sinatrarb.com) that allows you to easily create a Facebook application by using the Facebooker gem.
+
+Written by Ron Evans (http://www.deadprogrammersociety.com)
+
+Based on merb_facebooker (http://github.com/vanpelt/merb_facebooker) by Chris Van Pelt, which was based on
+the Rails classes in Facebooker (http://facebooker.rubyforge.org/) by Mike Mangino, Shane Vitarana, & Chad Fowler
+
+Thanks, everyone!
+
+= Here is a very simple example application:
+
+ require 'rubygems'
+ require 'frankie'
+
+ configure do
+ set_option :sessions, true
+ load_facebook_config "./config/facebooker.yml", Sinatra.env
+ end
+
+ ## facebooker helpers
+ before do
+ ensure_authenticated_to_facebook
+ ensure_application_is_installed_by_facebook_user
+ end
+
+ ## the site
+ get '/' do
+ body "<h1>Hello #{session['facebook_session'].user.name} and welcome to frankie!</h1>"
+ end
+
+
+= How to use frankie
+- Install the frankie gem (which will install both Sinatra and Facebooker if you do not already have them)
+ sudo gem install frankie
+
+- Create the application directories for your new app
+ mkdir myapp
+ cd myapp
+ mkdir config
+
+- Put your facebooker.yml file into the /myapp/config directory, and set the values to your information. Here is a simple example of the file:
+
+ development:
+ api_key: apikeyhere
+ secret_key: secretkeyhere
+ canvas_page_name: yourcanvashere
+ callback_url: http://localhost:4567
+ test:
+ api_key: apikeyhere
+ secret_key: secretkeyhere
+ canvas_page_name: yourcanvashere
+ callback_url: http://localhost:4567
+ production:
+ api_key: apikeyhere
+ secret_key: secretkeyhere
+ canvas_page_name: yourcanvashere
+ callback_url: http://yourrealserver.com
+
+
+- Make sure you have setup your Facebook application on the facebook site. Google "setup new facebook application" if you are unsure how to do this. I recommend starting with an IFrame application. A more advanced and cooler approach uses a tunneling script like this one: http://pastie.caboo.se/178903
+
+- Create your application, based on the sample above, and then run it:
+ruby sample.rb
+
+- Test your app by going to http://apps.facebook.com/yourappname
+
+Have fun!
View
29 Rakefile
@@ -0,0 +1,29 @@
+require 'rubygems'
+require 'rake/testtask'
+require 'rake/rdoctask'
+require 'echoe'
+
+task :default => :test
+
+Rake::RDocTask.new do |rd|
+ rd.main = "README.rdoc"
+ rd.rdoc_files += ["README.rdoc"]
+ rd.rdoc_files += Dir.glob("lib/**/*.rb")
+ rd.rdoc_dir = 'doc'
+end
+
+Rake::TestTask.new do |t|
+ ENV['SINATRA_ENV'] = 'test'
+ t.pattern = File.dirname(__FILE__) + "/test/*_test.rb"
+end
+
+Echoe.new("frankie") do |p|
+ p.author = "Ron Evans"
+ p.summary = "Easy creation of Facebook applications in Ruby using plugin for Sinatra web framework that integrates with Facebooker gem."
+ p.url = "http://facethesinatra.com/"
+# p.docs_host = "sinatrarb.com:/var/www/blakemizerany.com/public/docs/"
+ p.dependencies = ["sinatra >=0.2.0", "facebooker >=0.9.5"]
+ p.install_message = "*** Frankie was installed ***"
+ p.include_rakefile = true
+end
+
View
315 lib/frankie.rb
@@ -6,176 +6,181 @@
# and the Rails classes in Facebooker (http://facebooker.rubyforge.org/) from Mike Mangino, Shane Vitarana, & Chad Fowler
#
-module Sinatra
-
- module Frankie # :nodoc:
-
- module Dsl
-
- def load_facebook_config(file, env=:development)
- if File.exist?(file)
- yaml = YAML.load_file(file)[env.to_s]
- ENV['FACEBOOK_API_KEY'] = yaml['api_key']
- ENV['FACEBOOK_SECRET_KEY'] = yaml['secret_key']
- ENV['FACEBOOKER_RELATIVE_URL_ROOT'] = yaml['canvas_page_name']
- end
+require 'sinatra'
+
+module Frankie
+
+ module Loader
+
+ require "yaml"
+
+ def load_facebook_config(file, env=:development)
+ if File.exist?(file)
+ yaml = YAML.load_file(file)[env.to_s]
+ ENV['FACEBOOK_API_KEY'] = yaml['api_key']
+ ENV['FACEBOOK_SECRET_KEY'] = yaml['secret_key']
+ ENV['FACEBOOKER_RELATIVE_URL_ROOT'] = yaml['canvas_page_name']
end
-
end
-
- module EventContext
+
+ end
+
+ module EventContext
- require "facebooker"
-
- def facebook_session
- @facebook_session
- end
-
- def facebook_session_parameters
- {:fb_sig_session_key=>params[:fb_sig_session_key]}
- end
-
- def set_facebook_session
- session_set = session_already_secured? || secure_with_token! || secure_with_facebook_params!
- if session_set
- capture_facebook_friends_if_available!
- Facebooker::Session.current = facebook_session
- end
- session_set
- end
-
- def facebook_params
- @facebook_params ||= verified_facebook_params
- end
-
- private
-
- def session_already_secured?
- (@facebook_session = session[:facebook_session]) && session[:facebook_session].secured?
- end
-
- def secure_with_token!
- if params[:auth_token]
- @facebook_session = new_facebook_session
- @facebook_session.auth_token = params[:auth_token]
- @facebook_session.secure!
- session[:facebook_session] = @facebook_session
- end
- end
-
- def secure_with_facebook_params!
- return unless request_is_for_a_facebook_canvas?
-
- if ['user', 'session_key'].all? {|element| facebook_params[element]}
- @facebook_session = new_facebook_session
- @facebook_session.secure_with!(facebook_params['session_key'], facebook_params['user'], facebook_params['expires'])
- session[:facebook_session] = @facebook_session
- end
+ require "facebooker"
+
+ def facebook_session
+ @facebook_session
+ end
+
+ def facebook_session_parameters
+ {:fb_sig_session_key=>params["fb_sig_session_key"]}
+ end
+
+ def set_facebook_session
+ session_set = session_already_secured? || secure_with_token! || secure_with_facebook_params!
+ if session_set
+ capture_facebook_friends_if_available!
+ Facebooker::Session.current = facebook_session
end
-
- def create_new_facebook_session_and_redirect!
- session[:facebook_session] = new_facebook_session
- throw :halt, do_redirect(session[:facebook_session].login_url) unless @installation_required
+ session_set
+ end
+
+ def facebook_params
+ @facebook_params ||= verified_facebook_params
+ end
+
+ private
+
+ def session_already_secured?
+ (@facebook_session = session['facebook_session']) && session['facebook_session'].secured?
+ end
+
+ def secure_with_token!
+ if params['auth_token']
+ @facebook_session = new_facebook_session
+ @facebook_session.auth_token = params['auth_token']
+ @facebook_session.secure!
+ session['facebook_session'] = @facebook_session
end
+ end
+
+ def secure_with_facebook_params!
+ return unless request_is_for_a_facebook_canvas?
- def new_facebook_session
- Facebooker::Session.create(Facebooker::Session.api_key, Facebooker::Session.secret_key)
+ if ['user', 'session_key'].all? {|element| facebook_params[element]}
+ @facebook_session = new_facebook_session
+ @facebook_session.secure_with!(facebook_params['session_key'], facebook_params['user'], facebook_params['expires'])
+ session[:facebook_session] = @facebook_session
end
-
- def capture_facebook_friends_if_available!
- return unless request_is_for_a_facebook_canvas?
- if friends = facebook_params['friends']
- facebook_session.user.friends = friends.map do |friend_uid|
- User.new(friend_uid, facebook_session)
- end
+ end
+
+ def create_new_facebook_session_and_redirect!
+ s = new_facebook_session
+ session['facebook_session'] = s
+ throw :halt, do_redirect(session['facebook_session'].login_url) unless @installation_required
+ end
+
+ def new_facebook_session
+ Facebooker::Session.create(Facebooker::Session.api_key, Facebooker::Session.secret_key)
+ end
+
+ def capture_facebook_friends_if_available!
+ return unless request_is_for_a_facebook_canvas?
+ if friends = facebook_params['friends']
+ facebook_session.user.friends = friends.map do |friend_uid|
+ User.new(friend_uid, facebook_session)
end
end
-
- def blank?(value)
- (value == '0' || value.nil? || value == '')
- end
+ end
+
+ def blank?(value)
+ (value == '0' || value.nil? || value == '')
+ end
- def verified_facebook_params
- facebook_sig_params = params.inject({}) do |collection, pair|
- collection[pair.first.to_s.sub(/^fb_sig_/, '')] = pair.last if pair.first.to_s[0,7] == 'fb_sig_'
- collection
- end
- verify_signature(facebook_sig_params,params[:fb_sig])
- facebook_sig_params.inject(Hash.new) do |collection, pair|
- collection[pair.first] = facebook_parameter_conversions[pair.first].call(pair.last)
- collection
- end
+ def verified_facebook_params
+ facebook_sig_params = params.inject({}) do |collection, pair|
+ collection[pair.first.sub(/^fb_sig_/, '')] = pair.last if pair.first[0,7] == 'fb_sig_'
+ collection
end
-
- # 48.hours.ago in sinatra
- def earliest_valid_session
- now = Time.now
- now -= (60 * 60 * 48)
- now
- end
-
- def verify_signature(facebook_sig_params,expected_signature)
- raw_string = facebook_sig_params.map{ |*args| args.join('=') }.sort.join
- actual_sig = Digest::MD5.hexdigest([raw_string, Facebooker::Session.secret_key].join)
- raise Facebooker::Session::IncorrectSignature if actual_sig != expected_signature
- raise Facebooker::Session::SignatureTooOld if Time.at(facebook_sig_params['time'].to_f) < earliest_valid_session
- true
+ verify_signature(facebook_sig_params, params['fb_sig'])
+ facebook_sig_params.inject(Hash.new) do |collection, pair|
+ collection[pair.first] = facebook_parameter_conversions[pair.first].call(pair.last)
+ collection
end
-
- def facebook_parameter_conversions
- @facebook_parameter_conversions ||= Hash.new do |hash, key|
- lambda{|value| value}
- end.merge(
- 'time' => lambda{|value| Time.at(value.to_f)},
- 'in_canvas' => lambda{|value| !blank?(value)},
- 'added' => lambda{|value| !blank?(value)},
- 'expires' => lambda{|value| blank?(value) ? nil : Time.at(value.to_f)},
- 'friends' => lambda{|value| value.split(/,/)}
- )
- end
-
- def do_redirect(*args)
- if request_is_for_a_facebook_canvas?
- fbml_redirect_tag(args)
- else
- redirect args[0]
- end
- end
-
- def fbml_redirect_tag(url)
- "<fb:redirect url=\"#{url}\" />"
- end
-
- def request_is_for_a_facebook_canvas?
- return false if !params[:fb_sig_in_canvas]
- !params[:fb_sig_in_canvas].blank?
- end
-
- def application_is_installed?
- facebook_params['added']
- end
-
- def ensure_authenticated_to_facebook
- set_facebook_session || create_new_facebook_session_and_redirect!
- end
-
- def ensure_application_is_installed_by_facebook_user
- @installation_required = true
- authenticated_and_installed = ensure_authenticated_to_facebook && application_is_installed?
- application_is_not_installed_by_facebook_user unless authenticated_and_installed
- authenticated_and_installed
- end
-
- def application_is_not_installed_by_facebook_user
- throw :halt, do_redirect(session[:facebook_session].install_url)
- end
-
- def set_fbml_format
- params[:format]="fbml" if request_is_for_a_facebook_canvas?
+ end
+
+ # 48.hours.ago in sinatra
+ def earliest_valid_session
+ now = Time.now
+ now -= (60 * 60 * 48)
+ now
+ end
+
+ def verify_signature(facebook_sig_params,expected_signature)
+ raw_string = facebook_sig_params.map{ |*args| args.join('=') }.sort.join
+ actual_sig = Digest::MD5.hexdigest([raw_string, Facebooker::Session.secret_key].join)
+ raise Facebooker::Session::IncorrectSignature if actual_sig != expected_signature
+ raise Facebooker::Session::SignatureTooOld if Time.at(facebook_sig_params['time'].to_f) < earliest_valid_session
+ true
+ end
+
+ def facebook_parameter_conversions
+ @facebook_parameter_conversions ||= Hash.new do |hash, key|
+ lambda{|value| value}
+ end.merge(
+ 'time' => lambda{|value| Time.at(value.to_f)},
+ 'in_canvas' => lambda{|value| !blank?(value)},
+ 'added' => lambda{|value| !blank?(value)},
+ 'expires' => lambda{|value| blank?(value) ? nil : Time.at(value.to_f)},
+ 'friends' => lambda{|value| value.split(/,/)}
+ )
+ end
+
+ def do_redirect(*args)
+ if request_is_for_a_facebook_canvas?
+ fbml_redirect_tag(args[0])
+ else
+ redirect args[0]
end
-
end
+ def fbml_redirect_tag(url)
+ "<fb:redirect url=\"#{url}\" />"
+ end
+
+ def request_is_for_a_facebook_canvas?
+ return false if !params["fb_sig_in_canvas"]
+ !params["fb_sig_in_canvas"].blank?
+ end
+
+ def application_is_installed?
+ facebook_params['added']
+ end
+
+ def ensure_authenticated_to_facebook
+ set_facebook_session || create_new_facebook_session_and_redirect!
+ end
+
+ def ensure_application_is_installed_by_facebook_user
+ @installation_required = true
+ authenticated_and_installed = ensure_authenticated_to_facebook && application_is_installed?
+ application_is_not_installed_by_facebook_user unless authenticated_and_installed
+ authenticated_and_installed
+ end
+
+ def application_is_not_installed_by_facebook_user
+ throw :halt, do_redirect(session['facebook_session'].install_url)
+ end
+
+ def set_fbml_format
+ params['format']="fbml" if request_is_for_a_facebook_canvas?
+ end
+
end
end
+
+# extend sinatra with frankie methods
+Sinatra::EventContext.send(:include, Frankie::EventContext)
+include Frankie::Loader
View
6 test/frankie_test.rb
@@ -0,0 +1,6 @@
+require File.dirname(__FILE__) + '/helper'
+
+context "frankie" do
+ it "should be a placeholder for a real test"
+end
+
View
4 test/helper.rb
@@ -0,0 +1,4 @@
+require 'rubygems'
+require 'sinatra'
+require File.dirname(__FILE__) + '/../lib/frankie'
+require 'sinatra/test/spec'

0 comments on commit d53ba0c

Please sign in to comment.