palidanx-fb_graph 1.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +21 -0
- data/LICENSE +20 -0
- data/README.rdoc +308 -0
- data/Rakefile +49 -0
- data/VERSION +1 -0
- data/assets/fb_graph.ai +1726 -6
- data/assets/fb_graph.png +0 -0
- data/fb_graph.gemspec +327 -0
- data/lib/fb_graph.rb +75 -0
- data/lib/fb_graph/album.rb +133 -0
- data/lib/fb_graph/application.rb +57 -0
- data/lib/fb_graph/auth.rb +52 -0
- data/lib/fb_graph/auth/cookie.rb +43 -0
- data/lib/fb_graph/checkin.rb +44 -0
- data/lib/fb_graph/collection.rb +44 -0
- data/lib/fb_graph/comment.rb +20 -0
- data/lib/fb_graph/comparison.rb +9 -0
- data/lib/fb_graph/connection.rb +30 -0
- data/lib/fb_graph/connections.rb +3 -0
- data/lib/fb_graph/connections/accounts.rb +58 -0
- data/lib/fb_graph/connections/activities.rb +14 -0
- data/lib/fb_graph/connections/albums.rb +96 -0
- data/lib/fb_graph/connections/attending.rb +18 -0
- data/lib/fb_graph/connections/books.rb +14 -0
- data/lib/fb_graph/connections/checkins.rb +22 -0
- data/lib/fb_graph/connections/comments.rb +39 -0
- data/lib/fb_graph/connections/declined.rb +18 -0
- data/lib/fb_graph/connections/events.rb +21 -0
- data/lib/fb_graph/connections/feed.rb +90 -0
- data/lib/fb_graph/connections/friends.rb +14 -0
- data/lib/fb_graph/connections/groups.rb +14 -0
- data/lib/fb_graph/connections/home.rb +14 -0
- data/lib/fb_graph/connections/insights.rb +13 -0
- data/lib/fb_graph/connections/interests.rb +14 -0
- data/lib/fb_graph/connections/invited.rb +14 -0
- data/lib/fb_graph/connections/likes.rb +16 -0
- data/lib/fb_graph/connections/links.rb +21 -0
- data/lib/fb_graph/connections/maybe.rb +18 -0
- data/lib/fb_graph/connections/members.rb +14 -0
- data/lib/fb_graph/connections/movies.rb +14 -0
- data/lib/fb_graph/connections/music.rb +14 -0
- data/lib/fb_graph/connections/noreply.rb +14 -0
- data/lib/fb_graph/connections/notes.rb +21 -0
- data/lib/fb_graph/connections/photos.rb +21 -0
- data/lib/fb_graph/connections/picture.rb +14 -0
- data/lib/fb_graph/connections/posts.rb +14 -0
- data/lib/fb_graph/connections/statuses.rb +14 -0
- data/lib/fb_graph/connections/subscriptions.rb +53 -0
- data/lib/fb_graph/connections/tagged.rb +14 -0
- data/lib/fb_graph/connections/television.rb +14 -0
- data/lib/fb_graph/connections/videos.rb +14 -0
- data/lib/fb_graph/education.rb +25 -0
- data/lib/fb_graph/event.rb +47 -0
- data/lib/fb_graph/group.rb +27 -0
- data/lib/fb_graph/insight.rb +14 -0
- data/lib/fb_graph/link.rb +28 -0
- data/lib/fb_graph/node.rb +121 -0
- data/lib/fb_graph/note.rb +28 -0
- data/lib/fb_graph/page.rb +41 -0
- data/lib/fb_graph/photo.rb +41 -0
- data/lib/fb_graph/post.rb +50 -0
- data/lib/fb_graph/searchable.rb +25 -0
- data/lib/fb_graph/searchable/result.rb +31 -0
- data/lib/fb_graph/status.rb +23 -0
- data/lib/fb_graph/subscription.rb +14 -0
- data/lib/fb_graph/tag.rb +16 -0
- data/lib/fb_graph/user.rb +89 -0
- data/lib/fb_graph/venue.rb +17 -0
- data/lib/fb_graph/video.rb +28 -0
- data/lib/fb_graph/work.rb +35 -0
- data/spec/fake_json/albums/photos/matake_private.json +97 -0
- data/spec/fake_json/albums/photos/post_with_valid_access_token.json +1 -0
- data/spec/fake_json/applications/subscriptions/fb_graph_private.json +12 -0
- data/spec/fake_json/checkins/search_private.json +54 -0
- data/spec/fake_json/checkins/search_public.json +6 -0
- data/spec/fake_json/events/attending/post_with_valid_access_token.json +1 -0
- data/spec/fake_json/events/attending/smartday_private.json +44 -0
- data/spec/fake_json/events/declined/post_with_valid_access_token.json +1 -0
- data/spec/fake_json/events/declined/smartday_private.json +720 -0
- data/spec/fake_json/events/invited/smartday_private.json +7092 -0
- data/spec/fake_json/events/maybe/post_with_valid_access_token.json +1 -0
- data/spec/fake_json/events/maybe/smartday_private.json +956 -0
- data/spec/fake_json/events/noreply/smartday_private.json +896 -0
- data/spec/fake_json/groups/members/emacs_private.json +1996 -0
- data/spec/fake_json/pages/checkins/gowalla_private.json +113 -0
- data/spec/fake_json/pages/checkins/gowalla_public.json +6 -0
- data/spec/fake_json/pages/notes/post_with_valid_access_token.json +1 -0
- data/spec/fake_json/pages/platform_private.json +13 -0
- data/spec/fake_json/pages/platform_public.json +13 -0
- data/spec/fake_json/pages/statuses/platform_private.json +258 -0
- data/spec/fake_json/pages/statuses/platform_public.json +6 -0
- data/spec/fake_json/posts/comments/post_with_invalid_access_token.json +1 -0
- data/spec/fake_json/posts/comments/post_with_valid_access_token.json +1 -0
- data/spec/fake_json/posts/comments/post_without_access_token.json +1 -0
- data/spec/fake_json/posts/likes/post_with_invalid_access_token.json +1 -0
- data/spec/fake_json/posts/likes/post_with_valid_access_token.json +1 -0
- data/spec/fake_json/posts/likes/post_without_access_token.json +1 -0
- data/spec/fake_json/posts/platform_private.json +97 -0
- data/spec/fake_json/posts/platform_public.json +52 -0
- data/spec/fake_json/users/accounts/matake_private.json +14 -0
- data/spec/fake_json/users/accounts/matake_private_with_manage_pages_permission.json +16 -0
- data/spec/fake_json/users/accounts/matake_public.json +6 -0
- data/spec/fake_json/users/activities/arjun_private.json +24 -0
- data/spec/fake_json/users/activities/arjun_public.json +6 -0
- data/spec/fake_json/users/albums/matake_private.json +36 -0
- data/spec/fake_json/users/albums/matake_public.json +6 -0
- data/spec/fake_json/users/albums/post_with_valid_access_token.json +1 -0
- data/spec/fake_json/users/arjun_private.json +109 -0
- data/spec/fake_json/users/arjun_public.json +12 -0
- data/spec/fake_json/users/books/matake_private.json +9 -0
- data/spec/fake_json/users/books/matake_public.json +6 -0
- data/spec/fake_json/users/checkins/mattt_private.json +389 -0
- data/spec/fake_json/users/checkins/mattt_public.json +6 -0
- data/spec/fake_json/users/events/matake_private.json +71 -0
- data/spec/fake_json/users/events/matake_public.json +6 -0
- data/spec/fake_json/users/events/post_with_valid_access_token.json +1 -0
- data/spec/fake_json/users/feed/arjun_private.json +520 -0
- data/spec/fake_json/users/feed/arjun_public.json +520 -0
- data/spec/fake_json/users/feed/post_with_invalid_access_token.json +1 -0
- data/spec/fake_json/users/feed/post_with_valid_access_token.json +1 -0
- data/spec/fake_json/users/feed/post_without_access_token.json +1 -0
- data/spec/fake_json/users/friends/arjun_private.json +6 -0
- data/spec/fake_json/users/friends/arjun_public.json +6 -0
- data/spec/fake_json/users/friends/me_private.json +524 -0
- data/spec/fake_json/users/friends/me_public.json +6 -0
- data/spec/fake_json/users/groups/matake_private.json +48 -0
- data/spec/fake_json/users/groups/matake_public.json +6 -0
- data/spec/fake_json/users/home/arjun_private.json +6 -0
- data/spec/fake_json/users/home/arjun_public.json +6 -0
- data/spec/fake_json/users/home/me_private.json +460 -0
- data/spec/fake_json/users/home/me_private_next.json +382 -0
- data/spec/fake_json/users/home/me_private_previous.json +36 -0
- data/spec/fake_json/users/home/me_public.json +6 -0
- data/spec/fake_json/users/interests/matake_private.json +14 -0
- data/spec/fake_json/users/likes/arjun_private.json +1394 -0
- data/spec/fake_json/users/likes/arjun_public.json +6 -0
- data/spec/fake_json/users/links/matake_private.json +221 -0
- data/spec/fake_json/users/links/post_with_valid_access_token.json +1 -0
- data/spec/fake_json/users/me_private.json +128 -0
- data/spec/fake_json/users/me_public.json +6 -0
- data/spec/fake_json/users/movies/matake_private.json +9 -0
- data/spec/fake_json/users/music/matake_private.json +34 -0
- data/spec/fake_json/users/notes/matake_private.json +308 -0
- data/spec/fake_json/users/posts/arjun_private.json +386 -0
- data/spec/fake_json/users/posts/arjun_public.json +386 -0
- data/spec/fake_json/users/statuses/arjun_private.json +233 -0
- data/spec/fake_json/users/statuses/arjun_public.json +6 -0
- data/spec/fake_json/users/tagged/arjun_private.json +308 -0
- data/spec/fake_json/users/tagged/arjun_public.json +308 -0
- data/spec/fake_json/users/television/matake_private.json +9 -0
- data/spec/fake_json/users/videos/kirk_private.json +41 -0
- data/spec/fb_graph/album_spec.rb +61 -0
- data/spec/fb_graph/application_spec.rb +23 -0
- data/spec/fb_graph/auth_spec.rb +35 -0
- data/spec/fb_graph/checkin_spec.rb +29 -0
- data/spec/fb_graph/collection_spec.rb +45 -0
- data/spec/fb_graph/comment_spec.rb +31 -0
- data/spec/fb_graph/connection_spec.rb +38 -0
- data/spec/fb_graph/connections/accounts_spec.rb +47 -0
- data/spec/fb_graph/connections/activities_spec.rb +34 -0
- data/spec/fb_graph/connections/albums_spec.rb +60 -0
- data/spec/fb_graph/connections/attending_spec.rb +24 -0
- data/spec/fb_graph/connections/books_spec.rb +33 -0
- data/spec/fb_graph/connections/checkins_spec.rb +109 -0
- data/spec/fb_graph/connections/comments_spec.rb +85 -0
- data/spec/fb_graph/connections/declined_spec.rb +24 -0
- data/spec/fb_graph/connections/events_spec.rb +53 -0
- data/spec/fb_graph/connections/feed_spec.rb +102 -0
- data/spec/fb_graph/connections/friends_spec.rb +50 -0
- data/spec/fb_graph/connections/groups_spec.rb +32 -0
- data/spec/fb_graph/connections/home_spec.rb +58 -0
- data/spec/fb_graph/connections/interests_spec.rb +14 -0
- data/spec/fb_graph/connections/invited_spec.rb +14 -0
- data/spec/fb_graph/connections/likes_spec.rb +33 -0
- data/spec/fb_graph/connections/links_spec.rb +33 -0
- data/spec/fb_graph/connections/maybe_spec.rb +24 -0
- data/spec/fb_graph/connections/members_spec.rb +14 -0
- data/spec/fb_graph/connections/movies_spec.rb +14 -0
- data/spec/fb_graph/connections/music_spec.rb +14 -0
- data/spec/fb_graph/connections/noreply_spec.rb +14 -0
- data/spec/fb_graph/connections/notes_spec.rb +32 -0
- data/spec/fb_graph/connections/photos_spec.rb +30 -0
- data/spec/fb_graph/connections/picture_spec.rb +29 -0
- data/spec/fb_graph/connections/posts_spec.rb +35 -0
- data/spec/fb_graph/connections/statuses_spec.rb +74 -0
- data/spec/fb_graph/connections/subscriptions_spec.rb +18 -0
- data/spec/fb_graph/connections/tagged_spec.rb +42 -0
- data/spec/fb_graph/connections/television_spec.rb +14 -0
- data/spec/fb_graph/connections/videos_spec.rb +14 -0
- data/spec/fb_graph/education_spec.rb +61 -0
- data/spec/fb_graph/event_spec.rb +50 -0
- data/spec/fb_graph/group_spec.rb +46 -0
- data/spec/fb_graph/insight_spec.rb +17 -0
- data/spec/fb_graph/link_spec.rb +43 -0
- data/spec/fb_graph/node_spec.rb +13 -0
- data/spec/fb_graph/note_spec.rb +37 -0
- data/spec/fb_graph/page_spec.rb +56 -0
- data/spec/fb_graph/photo_spec.rb +60 -0
- data/spec/fb_graph/post_spec.rb +71 -0
- data/spec/fb_graph/status_spec.rb +31 -0
- data/spec/fb_graph/subscription_spec.rb +5 -0
- data/spec/fb_graph/tag_spec.rb +20 -0
- data/spec/fb_graph/user_spec.rb +139 -0
- data/spec/fb_graph/venue_spec.rb +23 -0
- data/spec/fb_graph/video_spec.rb +37 -0
- data/spec/fb_graph/work_spec.rb +67 -0
- data/spec/helpers/fake_json_helper.rb +11 -0
- data/spec/spec.opts +3 -0
- data/spec/spec_helper.rb +18 -0
- metadata +414 -0
@@ -0,0 +1,57 @@
|
|
1
|
+
module FbGraph
|
2
|
+
class Application < Node
|
3
|
+
include Connections::Feed
|
4
|
+
include Connections::Posts
|
5
|
+
include Connections::Picture
|
6
|
+
include Connections::Tagged
|
7
|
+
include Connections::Links
|
8
|
+
include Connections::Photos
|
9
|
+
include Connections::Albums
|
10
|
+
include Connections::Statuses
|
11
|
+
include Connections::Videos
|
12
|
+
include Connections::Notes
|
13
|
+
include Connections::Events
|
14
|
+
include Connections::Subscriptions
|
15
|
+
include Connections::Insights
|
16
|
+
|
17
|
+
attr_accessor :name, :description, :category, :link, :secret
|
18
|
+
|
19
|
+
def initialize(client_id, attributes = {})
|
20
|
+
super
|
21
|
+
@name = attributes[:name]
|
22
|
+
@description = attributes[:description]
|
23
|
+
@category = attributes[:category]
|
24
|
+
@link = attributes[:link]
|
25
|
+
@secret = attributes[:secret]
|
26
|
+
end
|
27
|
+
|
28
|
+
# == Get OAuth access token
|
29
|
+
#
|
30
|
+
# Obtain an OAuth access token associated with your application via the OAuth Client Credentials Flow.
|
31
|
+
#
|
32
|
+
# ref) http://developers.facebook.com/docs/api#analytics
|
33
|
+
#
|
34
|
+
# app = FbGraph::Application.new(APP_ID)
|
35
|
+
# app.get_access_token
|
36
|
+
# # => access token as String
|
37
|
+
# app.access_token # once get_access_token is called, access token is cached.
|
38
|
+
# # => access token as String
|
39
|
+
#
|
40
|
+
# This method is automatically called when access token needed and application secret has already given.
|
41
|
+
#
|
42
|
+
# app = FbGraph::Application.new(APP_ID, :secret => APP_SECRET)
|
43
|
+
# app.subscriptions # get_access_token is called automatically
|
44
|
+
# # => Array of FbGraph::Subscription
|
45
|
+
def get_access_token(secret = nil)
|
46
|
+
self.secret ||= secret
|
47
|
+
auth = FbGraph::Auth.new(self.identifier, self.secret)
|
48
|
+
response_string = auth.client.request(:post, auth.client.access_token_url, {
|
49
|
+
:client_id => self.identifier,
|
50
|
+
:client_secret => self.secret,
|
51
|
+
:type => 'client_cred'
|
52
|
+
})
|
53
|
+
self.access_token = response_string.split('=').last
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module FbGraph
|
2
|
+
# = Parse & verify facebook auth cookie
|
3
|
+
#
|
4
|
+
# Used with Facebook JavaScript SDK
|
5
|
+
#
|
6
|
+
# app = FbGraph::Auth.new(APP_ID, APP_SECRET)
|
7
|
+
# app.from_cookie(cookie_hash)
|
8
|
+
# auth.access_token
|
9
|
+
# # => OAuth2::AccessToken (not String!)
|
10
|
+
# auth.user # only initialized
|
11
|
+
# auth.user.fetch # fetch whole profile
|
12
|
+
#
|
13
|
+
# This method is called automatically if cookie is given when initializing
|
14
|
+
#
|
15
|
+
# auth = FbGraph::Auth.new(APP_ID, APP_SECRET, :cookie => {..})
|
16
|
+
# auth.access_token # already parsed
|
17
|
+
class Auth
|
18
|
+
class VerificationFailed < FbGraph::Exception; end
|
19
|
+
|
20
|
+
attr_accessor :client, :access_token, :user
|
21
|
+
|
22
|
+
def initialize(client_id, client_secret, options = {})
|
23
|
+
@client = OAuth2::Client.new(client_id, client_secret, options.merge(
|
24
|
+
:site => FbGraph::ROOT_URL
|
25
|
+
))
|
26
|
+
if options[:cookie].present?
|
27
|
+
from_cookie(options[:cookie])
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def from_cookie(cookie)
|
32
|
+
|
33
|
+
#this creates a cookie
|
34
|
+
cookie = FbGraph::Auth::Cookie.parse(self.client, cookie)
|
35
|
+
|
36
|
+
#the cookie expires time is the time as an integer
|
37
|
+
#in the oauth2 api, it does Time.now + expires, creating a time too large
|
38
|
+
#instead, make expires a delta value
|
39
|
+
time_expires = cookie[:expires].to_i - Time.now.to_i
|
40
|
+
self.access_token = OAuth2::AccessToken.new(
|
41
|
+
self.client,
|
42
|
+
cookie[:access_token],
|
43
|
+
cookie[:refresh_token],
|
44
|
+
time_expires
|
45
|
+
)
|
46
|
+
self.user = FbGraph::User.new(cookie[:uid], :access_token => self.access_token)
|
47
|
+
self
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
require 'fb_graph/auth/cookie'
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'digest/md5'
|
2
|
+
|
3
|
+
module FbGraph
|
4
|
+
class Auth
|
5
|
+
# NOTE:
|
6
|
+
# If you want access token, use FbGraph::Auth.new(APP_ID, APP_SECRET, :cookie => {..}) instead
|
7
|
+
class Cookie
|
8
|
+
def self.parse(client, cookie)
|
9
|
+
fb_cookie_string = if cookie.is_a?(Hash)
|
10
|
+
cookie["fbs_#{client.id}"]
|
11
|
+
else
|
12
|
+
cookie
|
13
|
+
end
|
14
|
+
|
15
|
+
raise VerificationFailed.new(401, 'Facebook cookie not found') if fb_cookie_string.blank?
|
16
|
+
|
17
|
+
fb_cookie_string.gsub!(/[\\"]/, '')
|
18
|
+
signature, fb_cookie = '', {}
|
19
|
+
fb_cookie_string.split('&').each do |kv|
|
20
|
+
k, v = kv.split('=')
|
21
|
+
if k == 'sig'
|
22
|
+
signature = v
|
23
|
+
else
|
24
|
+
v = v.to_i if ['uid', 'expires'].include?(k)
|
25
|
+
fb_cookie[k] = v
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
signature_base_string = fb_cookie.to_a.sort do |a, b|
|
30
|
+
a[0] <=> b[0] || a[1] <=> b[1]
|
31
|
+
end.map do |(k, v)|
|
32
|
+
"#{k}=#{v}"
|
33
|
+
end.join
|
34
|
+
|
35
|
+
unless Digest::MD5.hexdigest("#{signature_base_string}#{client.secret}") == signature
|
36
|
+
raise VerificationFailed.new(401, 'Facebook cookie signature invalid')
|
37
|
+
end
|
38
|
+
|
39
|
+
fb_cookie.with_indifferent_access
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module FbGraph
|
2
|
+
class Checkin < Node
|
3
|
+
extend Searchable
|
4
|
+
|
5
|
+
attr_accessor :from, :tags, :place, :message, :coordinates, :application, :created_time
|
6
|
+
|
7
|
+
def initialize(identifier, attributes = {})
|
8
|
+
super
|
9
|
+
if (from = attributes[:from])
|
10
|
+
@from = FbGraph::User.new(from.delete(:id), from)
|
11
|
+
end
|
12
|
+
@tags = []
|
13
|
+
if (tags = attributes[:tags])
|
14
|
+
FbGraph::Collection.new(tags).each do |user|
|
15
|
+
@tags << FbGraph::User.new(user.delete(:id), user)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
if (place = attributes[:place])
|
19
|
+
@place = FbGraph::Page.new(place.delete(:id), place)
|
20
|
+
end
|
21
|
+
@message = attributes[:message]
|
22
|
+
if (coordinates = attributes[:coordinates])
|
23
|
+
# NOTE: it seems this attributes isn't used now
|
24
|
+
@coordinates = FbGraph::Venue.new(location)
|
25
|
+
end
|
26
|
+
if (application = attributes[:application])
|
27
|
+
@application = FbGraph::Application.new(application.delete(:id), application)
|
28
|
+
end
|
29
|
+
if (created_time = attributes.delete(:created_time))
|
30
|
+
@created_time = Time.parse(created_time).utc
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# == Search for recent check-ins for an authorized user and his or her friends:
|
35
|
+
#
|
36
|
+
# FbGraph::Checkin.search(:access_token => ACCESS_TOKEN)
|
37
|
+
# # => Array of FbGraph::Checkin
|
38
|
+
def self.search(options = {})
|
39
|
+
# NOTE:
|
40
|
+
# checkin search doesn't support "q=***" parameter
|
41
|
+
super(nil, options)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module FbGraph
|
2
|
+
class Collection < Array
|
3
|
+
attr_reader :previous, :next, :total_count
|
4
|
+
|
5
|
+
def initialize(collection = nil)
|
6
|
+
collection = case collection
|
7
|
+
when Array
|
8
|
+
{:data => collection, :count => collection.size}
|
9
|
+
when Hash
|
10
|
+
collection[:data] ||= []
|
11
|
+
collection
|
12
|
+
when nil
|
13
|
+
collection = {:data => [], :count => 0}
|
14
|
+
else
|
15
|
+
raise "Invalid collection"
|
16
|
+
end
|
17
|
+
result = replace(collection[:data])
|
18
|
+
@total_count = collection[:count]
|
19
|
+
@previous, @next = {}, {}
|
20
|
+
if (paging = collection[:paging])
|
21
|
+
if paging[:previous]
|
22
|
+
@previous = fetch_params(paging[:previous])
|
23
|
+
end
|
24
|
+
if paging[:next]
|
25
|
+
@next = fetch_params(paging[:next])
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def fetch_params(url)
|
33
|
+
query = URI.parse(url).query
|
34
|
+
params = {}
|
35
|
+
query.split('&').each do |q|
|
36
|
+
key, value = q.split('=')
|
37
|
+
params[key] = URI.unescape(value)
|
38
|
+
end
|
39
|
+
params.delete_if do |k, v|
|
40
|
+
!['limit', 'offset', 'until', 'since'].include?(k)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module FbGraph
|
2
|
+
class Comment < Node
|
3
|
+
attr_accessor :from, :message, :created_time
|
4
|
+
|
5
|
+
def initialize(identifier, attributes = {})
|
6
|
+
super
|
7
|
+
if (from = attributes[:from])
|
8
|
+
@from = if from[:category]
|
9
|
+
FbGraph::Page.new(from.delete(:id), from)
|
10
|
+
else
|
11
|
+
FbGraph::User.new(from.delete(:id), from)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
@message = attributes[:message]
|
15
|
+
if attributes[:created_time]
|
16
|
+
@created_time = Time.parse(attributes[:created_time]).utc
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module FbGraph
|
2
|
+
class Connection < Collection
|
3
|
+
attr_accessor :collection, :connection, :owner, :options
|
4
|
+
|
5
|
+
def initialize(owner, connection, options = {})
|
6
|
+
@owner = owner
|
7
|
+
@options = options
|
8
|
+
@connection = connection
|
9
|
+
@collection = options.delete(:collection) || FbGraph::Collection.new
|
10
|
+
replace collection
|
11
|
+
end
|
12
|
+
|
13
|
+
def next(_options_ = {})
|
14
|
+
if self.collection.next.present?
|
15
|
+
self.owner.send(self.connection, self.options.merge(_options_).merge(self.collection.next))
|
16
|
+
else
|
17
|
+
self.class.new(self.owner, self.connection)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def previous(_options_ = {})
|
22
|
+
puts self.options.inspect
|
23
|
+
if self.collection.previous.present?
|
24
|
+
self.owner.send(self.connection, self.options.merge(_options_).merge(self.collection.previous))
|
25
|
+
else
|
26
|
+
self.class.new(self.owner, self.connection)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module FbGraph
|
2
|
+
module Connections
|
3
|
+
# = What's "accounts"?
|
4
|
+
#
|
5
|
+
# Pages owned by the current user.
|
6
|
+
#
|
7
|
+
# ref) http://developers.facebook.com/docs/api#impersonation
|
8
|
+
#
|
9
|
+
# = Authentication
|
10
|
+
#
|
11
|
+
# * Access token is required.
|
12
|
+
# * "manage_pages" permission is optional.
|
13
|
+
#
|
14
|
+
# If the "manage_pages" permission has been granted,
|
15
|
+
# this connection also yields access_tokens that can be used to query the Graph API on behalf of the page.
|
16
|
+
#
|
17
|
+
# ref) http://developers.facebook.com/docs/reference/api/user
|
18
|
+
#
|
19
|
+
# = Connected with
|
20
|
+
#
|
21
|
+
# * FbGraph::User
|
22
|
+
#
|
23
|
+
# == Fetch
|
24
|
+
#
|
25
|
+
# pages = FbGraph::User.me(ACCESS_TOKEN).accounts
|
26
|
+
# # => array of FbGraph::Page
|
27
|
+
# pages.first.access_token
|
28
|
+
# # => String if "manage_pages" permission has been granted, nil if not.
|
29
|
+
#
|
30
|
+
# = Notes
|
31
|
+
#
|
32
|
+
# == Access token of the page
|
33
|
+
#
|
34
|
+
# Using given access token, you can do those things as the page, not as yourself.
|
35
|
+
#
|
36
|
+
# * update the page's wall
|
37
|
+
# * create new page's album and upload photos into it
|
38
|
+
# * create and manage an event
|
39
|
+
# * etc.
|
40
|
+
#
|
41
|
+
# See RDoc for FbGraph::Page for more details.
|
42
|
+
#
|
43
|
+
# page = FbGraph::User.me(ACCESS_TOKEN).accounts.first
|
44
|
+
# page.access_token
|
45
|
+
# # => given because "manage_pages" permission has been granted.
|
46
|
+
# page.feed!(:message => 'Updating via FbGraph')
|
47
|
+
# # => update the page's wall, not the user's wall
|
48
|
+
module Accounts
|
49
|
+
def accounts(options = {})
|
50
|
+
accounts = self.connection(:accounts, options)
|
51
|
+
accounts.map! do |account|
|
52
|
+
account[:access_token] ||= options[:access_token] || self.access_token
|
53
|
+
FbGraph::Page.new(account.delete(:id), account)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module FbGraph
|
2
|
+
module Connections
|
3
|
+
module Activities
|
4
|
+
def activities(options = {})
|
5
|
+
activities = self.connection(:activities, options)
|
6
|
+
activities.map! do |activity|
|
7
|
+
FbGraph::Page.new(activity.delete(:id), activity.merge(
|
8
|
+
:access_token => options[:access_token] || self.access_token
|
9
|
+
))
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module FbGraph
|
2
|
+
module Connections
|
3
|
+
# = Authentication
|
4
|
+
#
|
5
|
+
# * Access token is required to fetch/create albums.
|
6
|
+
# * "publish_stream" permissin is required to create new album.
|
7
|
+
#
|
8
|
+
# = Connected with
|
9
|
+
#
|
10
|
+
# * FbGraph::Application
|
11
|
+
# * FbGraph::USer
|
12
|
+
# * FbGraph::Page
|
13
|
+
#
|
14
|
+
# = Example
|
15
|
+
#
|
16
|
+
# == Fetch albums
|
17
|
+
#
|
18
|
+
# me = FbGraph::User.me(ACCESS_TOKEN)
|
19
|
+
# me.albums
|
20
|
+
# # => Array of FbGraph::Album
|
21
|
+
#
|
22
|
+
# page = FbGraph::Page.new('fb_graph')
|
23
|
+
# page.albums
|
24
|
+
# # => Array of FbGraph::Album
|
25
|
+
#
|
26
|
+
# == Create an album
|
27
|
+
#
|
28
|
+
# me = FbGraph::User.me(ACCESS_TOKEN)
|
29
|
+
# album = me.album!(
|
30
|
+
# :name => 'FbGraph test',
|
31
|
+
# :message => 'hello world!',
|
32
|
+
# :description => 'hello world!'
|
33
|
+
# )
|
34
|
+
#
|
35
|
+
# page = FbGraph::Page.new('fb_graph', :access_token => ACCESS_TOKEN)
|
36
|
+
# album = page.album!(
|
37
|
+
# :name => 'FbGraph test',
|
38
|
+
# :message => 'hello world!',
|
39
|
+
# :description => 'hello world!'
|
40
|
+
# )
|
41
|
+
#
|
42
|
+
# = Notes
|
43
|
+
#
|
44
|
+
# == Attributes after created
|
45
|
+
#
|
46
|
+
# Only attributes you specified are saved in the created album object.
|
47
|
+
# If you want to access any other attributes, you need to fetch the album info via Graph API.
|
48
|
+
#
|
49
|
+
# me = FbGraph::User.me(ACCESS_TOKEN)
|
50
|
+
# album = me.album!(
|
51
|
+
# :name => 'FbGraph test',
|
52
|
+
# :message => 'hello world!',
|
53
|
+
# :description => 'hello world!'
|
54
|
+
# )
|
55
|
+
# album.name # => 'FbGraoh test'
|
56
|
+
# album.from # => nil
|
57
|
+
# album.created_time # => nil
|
58
|
+
# album.fetch
|
59
|
+
# album.from # => me
|
60
|
+
# album.created_time # => Sun Sep 12 01:18:36 +0900 2010
|
61
|
+
#
|
62
|
+
# == Bug of Graph API
|
63
|
+
#
|
64
|
+
# According facebook's document, the key for +description+ should be +description+ both when fetching and creating,
|
65
|
+
# but actually you need to use +message+ instead of +description+ only when creating.
|
66
|
+
# It probably facebook's bug, and it might be fixed suddenly.
|
67
|
+
# I highly recommend to send same value both as +description+ and +message+ when creating,
|
68
|
+
# then your code will work without any code change.
|
69
|
+
#
|
70
|
+
# ref) http://developers.facebook.com/docs/reference/api/album
|
71
|
+
#
|
72
|
+
# me = FbGraph::User.me(ACCESS_TOKEN)
|
73
|
+
# album = me.album!(
|
74
|
+
# :name => 'FbGraph test',
|
75
|
+
# :message => 'hello world!',
|
76
|
+
# :description => 'hello world!'
|
77
|
+
# )
|
78
|
+
module Albums
|
79
|
+
def albums(options = {})
|
80
|
+
albums = self.connection(:albums, options)
|
81
|
+
albums.map! do |album|
|
82
|
+
Album.new(album.delete(:id), album.merge(
|
83
|
+
:access_token => options[:access_token] || self.access_token
|
84
|
+
))
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def album!(options = {})
|
89
|
+
album = post(options.merge(:connection => 'albums'))
|
90
|
+
Album.new(album.delete(:id), options.merge(album).merge(
|
91
|
+
:access_token => options[:access_token] || self.access_token
|
92
|
+
))
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|