palidanx-fb_graph 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|