Created
June 6, 2010 17:41
-
-
Save pwnall/427739 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Wraps an OAuth2 access token for Facebook. | |
class FacebookToken < ActiveRecord::Base | |
# The user whose token this is. | |
belongs_to :user | |
validates :user, :presence => true | |
# A unique ID on the Facebook site for the user owning this token. | |
validates :external_uid, :length => 1..32, :presence => true | |
# The OAuth2 access token. | |
validates :access_token, :length => 1..128, :presence => true | |
# FBGraph client loaded with this access token. | |
def facebook_client | |
@client ||= FBGraphRails.fbclient(access_token) | |
end | |
# Finds or creates the model containing a token. | |
# | |
# If a model for the same user exists, the model is updated with the given | |
# token. Otherwise, a new model will be created, together with a user. | |
def self.for(access_token) | |
uid = uid_from_token access_token | |
token = self.where(:external_uid => uid).first | |
if token | |
token.access_token = access_token | |
else | |
token = FacebookToken.new :external_uid => uid, | |
:access_token => access_token | |
token.user = User.create_with_facebook_token token | |
end | |
token.save! | |
token | |
end | |
# Extracts the Facebook user ID from a OAuth2 token. | |
# | |
# This is a hack. It works based on the current format, but might break at any | |
# time. Hopefully, we'll eventually have an official way of pulling the UID | |
# out of an OAuth2 token. | |
def self.uid_from_token(access_token) | |
access_token.split('|')[1].split('-').last | |
end | |
end | |
# :nodoc: methods based on the Facebook API | |
class FacebookToken | |
# The albums belonging to this Facebook account. | |
# | |
# Returns an array with one Hash per album. Hashes have the following keys: | |
# :name:: the album's name | |
# :count:: the number of photos in the album | |
# :thumbnail:: a URL to the thumbnail of the album's main photo | |
def albums | |
facebook_client.selection.me.albums.limit(200).info!['data'].map do |album| | |
{ :name => album['name'], :id => album['id'], | |
:count => album['count'].to_i, | |
:thumbnail => facebook_client.selection.album(album['id']).picture } | |
end | |
end | |
# The photos in a Facebook album. | |
# | |
# Args: | |
# album_id:: the OpenGraph ID for the album to be enumerated | |
# photo_limit:: the maximum number of photos to be retrieved | |
# | |
# Returns an array with one Hash per photo. Hashes have the following keys: | |
# :name:: the photo's caption | |
# :id:: the photo's OpenGraph ID | |
# :thumbnail:: a URL to the photo's thumbnail | |
# :full:: a URL to the photo's full-size rendering | |
def photos_in_album(album_id, photo_limit = 200) | |
if album_id.to_s == external_uid.to_s | |
# NOTE: this is a workaround against a Facebook API bug: | |
# http://bugs.developers.facebook.com/show_bug.cgi?id=10083 | |
profile_id = external_uid.to_i | |
# http://wiki.developers.facebook.com/index.php/Profile_archive_album | |
aid = (profile_id < (1 << 32)) ? | |
((profile_id << 32) | ((1 << 32) - 3)).to_s : | |
"#{profile_id}_-3" | |
uri = "https://api.facebook.com/method/photos.get?access_token=" + | |
"#{URI.escape(access_token)}&aid=#{URI.escape aid}" | |
nokogiri = Nokogiri.parse Curl::Easy.perform(uri).body_str | |
nokogiri.css('photo').map do |photo| | |
{ :name => photo.css('caption').first.inner_text, | |
:id => photo.css('pid').first.inner_text, | |
:thumbnail => photo.css('src_small').first.inner_text, | |
:full => photo.css('src_big').first.inner_text } | |
end | |
else | |
facebook_client.selection.album(album_id).photos. | |
limit(photo_limit).info!['data'].map do |photo| | |
{ :name => photo['name'], :id => photo['id'], | |
:thumbnail => photo['picture'], :full => photo['source'] } | |
end | |
end | |
end | |
# The photos that the token's owner is tagged in. | |
# | |
# Args: | |
# photo_limit:: the maximum number of photos to be retrieved | |
# | |
# Returns an array with one Hash per photo. Hashes have the following keys: | |
# :name:: the photo's caption | |
# :id:: the photo's OpenGraph ID | |
# :thumbnail:: a URL to the photo's thumbnail | |
# :full:: a URL to the photo's full-size rendering | |
def photos_of_self(photo_limit = 200) | |
facebook_client.selection.me.photos.limit(photo_limit). | |
info!['data'].map do |photo| | |
{ :name => photo['name'], :id => photo['id'], | |
:thumbnail => photo['picture'], :full => photo['source'] } | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment