Skip to content

Commit

Permalink
Ported to new Heroku Facebook template
Browse files Browse the repository at this point in the history
  • Loading branch information
Pat Patterson committed Mar 14, 2012
1 parent cea5714 commit 54dd639
Show file tree
Hide file tree
Showing 9 changed files with 269 additions and 168 deletions.
4 changes: 2 additions & 2 deletions Gemfile
@@ -1,7 +1,7 @@
source :gemcutter

gem "sinatra"
gem "mogli"
gem "koala"
gem "json"
gem "httparty"
gem "thin"
Expand All @@ -14,4 +14,4 @@ gem 'dalli'

# STAGE 3
gem "data_mapper"
gem "dm-postgres-adapter"
gem "dm-postgres-adapter"
10 changes: 4 additions & 6 deletions Gemfile.lock
Expand Up @@ -60,16 +60,14 @@ GEM
multipart-post (~> 1.1)
rack (~> 1.1)
fastercsv (1.5.4)
hashie (1.1.0)
httparty (0.7.8)
crack (= 0.1.8)
json (1.5.4)
json_pure (1.5.4)
spruz (~> 0.2.8)
mogli (0.0.32)
hashie (~> 1.1.0)
httparty (>= 0.4.3)
multi_json (~> 1.0.3)
koala (1.3.0)
faraday (~> 0.7.0)
multi_json (~> 1.0)
multi_json (1.0.3)
multipart-post (1.1.5)
oauth2 (0.5.2)
Expand Down Expand Up @@ -97,7 +95,7 @@ DEPENDENCIES
dm-postgres-adapter
httparty
json
mogli
koala
oauth2
sinatra
thin
118 changes: 56 additions & 62 deletions app.rb
@@ -1,5 +1,5 @@
require "sinatra"
require "mogli"
require 'koala'
require "oauth2"
require "dalli"

Expand Down Expand Up @@ -77,17 +77,19 @@ def force_token
if settings.environment == :production && request.scheme != 'https'
redirect "https://#{request.env['HTTP_HOST']}"
end

# STAGE 3: Protect all non-auth, non-services URLs
unless request.path =~ /^\/auth/ || request.path =~ /^\/charity/
# Facebook session redirect
redirect "/auth/facebook" unless session[:at]
redirect "/auth/facebook" unless session[:access_token]

@client = Mogli::Client.new(session[:at])
puts "Created @client"
# Get base API Connection
@graph = Koala::Facebook::API.new(session[:access_token])

# Get the user object
@user = @graph.get_object("me")

@app = Mogli::Application.find(ENV["FACEBOOK_APP_ID"], @client)
@user = Mogli::User.find("me", @client)
# Get public details of current application
@app = @graph.get_object(ENV["FACEBOOK_APP_ID"])
end

# STAGE 1: Set up the Force.com OAuth2 client
Expand All @@ -103,44 +105,31 @@ def force_token
end

helpers do
def url(path)
base = "#{request.scheme}://#{request.env['HTTP_HOST']}"
base + path
def host
request.env['HTTP_HOST']
end

def scheme
request.scheme
end

# STAGE 3: set additional fields in Facebook dialog calls
def post_to_wall_url
["https://www.facebook.com/dialog/feed?",
"redirect_uri=#{url("/close")}",
"&display=popup",
"&app_id=#{@app.id}",
"&name=#{URI.escape("Heroku Cloudstock Charity Vote")}",
"&picture=#{URI.escape(url('/images/logo-heroku.png'))}",
"&caption=#{URI.escape("Vote for a charity donation")}",
"&description=#{URI.escape("Your vote counts too. Vote for a charity donation by Heroku at Cloudstock.")}",
"&link=#{url('/')}"].join
def url_no_scheme(path = '')
"//#{host}#{path}"
end

def send_to_friends_url(charity)
["https://www.facebook.com/dialog/feed?",
"redirect_uri=#{url("/close")}",
"&display=popup",
"&app_id=#{@app.id}",
"&name=#{URI.escape("Heroku Cloudstock Charity Vote")}",
"&picture=#{URI.escape(url('/' + charity['Logo_URL__c']))}",
"&caption=#{URI.escape("I voted for #{charity['Name']}!")}",
"&description=#{URI.escape("Your vote counts too. Vote for a charity donation by Heroku at Cloudstock.")}",
"&link=#{url('/')}"].join
def url(path = '')
"#{scheme}://#{host}#{path}"
end

def authenticator
@authenticator ||= Mogli::Authenticator.new(ENV["FACEBOOK_APP_ID"], ENV["FACEBOOK_SECRET"], url("/auth/facebook/callback"))
@authenticator ||= Koala::Facebook::OAuth.new(ENV["FACEBOOK_APP_ID"], ENV["FACEBOOK_SECRET"], url("/auth/facebook/callback"))
end

end

# the facebook session expired! reset ours and restart the process
error(Mogli::Client::HTTPException) do
session[:at] = nil
error(Koala::Facebook::APIError) do
session[:access_token] = nil
redirect "/auth/facebook"
end

Expand All @@ -155,19 +144,25 @@ def authenticator
end

get "/" do
# limit queries to 15 results
@client.default_params[:limit] = 15
if session[:access_token]
@friends = @graph.get_connections('me', 'friends')
@photos = @graph.get_connections('me', 'photos')
@likes = @graph.get_connections('me', 'likes').first(4)

# for other data you can always run fql
@friends_using_app = @graph.fql_query("SELECT uid, name, is_app_user, pic_square FROM user WHERE uid in (SELECT uid2 FROM friend WHERE uid1 = me()) AND is_app_user = 1")

# STAGE 1: Get list of charities
@charities = charities
# STAGE 1: Get list of charities
@charities = charities

# STAGE 3: Manage voting
@vote_counts = vote_counts
# STAGE 3: Manage voting
@vote_counts = vote_counts

@voted = Vote.first(:user_id => @user.id)
@voted = Vote.first(:user_id => @user['id'])

@votes = Vote.all(:order => :created_at.desc, :limit => 11)
@vote_total = Vote.count
@votes = Vote.all(:order => :created_at.desc, :limit => 11)
@vote_total = Vote.count
end

erb :index
end
Expand All @@ -181,7 +176,7 @@ def authenticator
post '/vote' do
begin
vote = Vote.create(
:user_id => @user.id,
:user_id => @user['id'],
:charity_id => charity(params[:charity_id])['Id']
)
success = vote.save
Expand All @@ -198,15 +193,19 @@ def authenticator
"<body onload='window.close();'/>"
end

get "/sign_out" do
session[:access_token] = nil
redirect '/'
end

get "/auth/facebook" do
session[:at]=nil
redirect authenticator.authorize_url(:scope => FACEBOOK_SCOPE, :display => 'page')
session[:access_token] = nil
redirect authenticator.url_for_oauth_code(:permissions => FACEBOOK_SCOPE)
end

get '/auth/facebook/callback' do
client = Mogli::Client.create_from_code_and_authenticator(params[:code], authenticator)
session[:at] = client.access_token
redirect '/'
session[:access_token] = authenticator.get_access_token(params[:code])
redirect '/'
end

# STAGE 2: Flush charity cache
Expand All @@ -228,19 +227,14 @@ def charity(id)

def charities
# STAGE 2: Cache charities
# Could just use @charities ||= dalli_client.get(CHARITIES_KEY), but we want
# to explicitly show when we're using Memcache and when we're going to
# Force.com
unless @charities
@charities = dalli_client.get(CHARITIES_KEY)
if @charities
puts "***** Charities request served from Memcache"
else
puts "***** Querying Force.com for charities"
query = "SELECT Id, Name, Logo_URL__c, URL__c from Charity__c ORDER BY Name"
@charities = force_token.get("#{force_token.params['instance_url']}/services/data/v24.0/query/?q=#{CGI::escape(query)}").parsed['records']
dalli_client.set(CHARITIES_KEY, @charities)
end
@charities ||= dalli_client.get(CHARITIES_KEY)
if @charities
puts "***** Charities request served from memcache"
else
puts "***** Querying Force.com for charities"
query = "SELECT Id, Name, Logo_URL__c, URL__c from Charity__c ORDER BY Name"
@charities = force_token.get("#{force_token.params['instance_url']}/services/data/v24.0/query/?q=#{CGI::escape(query)}").parsed['records']
dalli_client.set(CHARITIES_KEY, @charities)
end
@charities
end
Expand Down
1 change: 1 addition & 0 deletions public/channel.html
@@ -0,0 +1 @@
<script src="//connect.facebook.net/en_US/all.js"></script>
Binary file modified public/images/sprites.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions public/javascripts/jquery-1.7.1.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion public/stylesheets/base.css
Expand Up @@ -47,7 +47,7 @@ header #user {
background-repeat: no-repeat;
background-position: left center;
}
header #action {
header #postToWall {
display: block;
position: absolute;
right: 6px;
Expand Down
19 changes: 19 additions & 0 deletions public/stylesheets/mobile.css
@@ -0,0 +1,19 @@
body {
margin: 10px;
width: auto;
}

#guides ul li,
#samples .list {
float: none;
margin: 0 auto 10px;
width: 172px;
}

#share-app li {
margin: 0 8px 4px 0;
}

#share-app {
width: auto;
}

0 comments on commit 54dd639

Please sign in to comment.