open_graph 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,6 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+
6
+ .DS_Store
@@ -0,0 +1,3 @@
1
+ [submodule "facebook-stub"]
2
+ path = facebook-stub
3
+ url = git://github.com/change/facebook-stub.git
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in open_graph.gemspec
4
+ gemspec
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,71 @@
1
+ # OpenGraph #
2
+
3
+ A ruby wrapper for the new [facebook graph api](http://developers.facebook.com/docs/reference/api/)
4
+
5
+ # Ruby #
6
+
7
+ ## Configuration ##
8
+
9
+ Gemfile
10
+
11
+ gem 'open_graph'
12
+
13
+ config/facebook.yml
14
+
15
+ development:
16
+ appid: YOUR_APP_ID
17
+ key: YOUR_APP_KEY
18
+ secret: YOUR_APP_SECRET
19
+ production:
20
+ ...
21
+
22
+ You'll have access to the config by `OpenGraph.config[:key]`
23
+
24
+ ## Initialization ##
25
+
26
+ ApplicationController::Base has access to `fb_open_graph`
27
+
28
+ `fb_open_graph` automatically parses and validates your facebook cookie like a boss.
29
+
30
+ ## API ##
31
+
32
+ fb_open_graph.valid?
33
+ will return true or false if you have a valid session.
34
+
35
+ fb_open_graph.use_manual_session!(new_facebook_id, new_access_token)
36
+ will force it to not use the cookie, but use your facebook\_id and\_access\_token instead
37
+
38
+ ### Get Calls ###
39
+
40
+ All get calls take an options hash, but not all get calls will use them. The calls which accept paging can take (:limit, :offset, :until, and :since).
41
+
42
+ fb_open_graph.info
43
+ will return a hash of information. possible keys may be `[:name, :email, :first_name, :middle_name, :last_name, :gender, :id, :locale :religion, :bio, :hometown, :birthday]`, etc. info[:location] returns a hash of `[:name, :city, :zip, :country, :id, :state]`
44
+
45
+ fb_open_graph.picture(:type => (square|small|large))
46
+ will return the a hash of `{:content_type => 'image/jpeg', :image => actual_image_data}`.
47
+
48
+ #### Other Get calls ####
49
+ friends, news_feed, profile_feed, likes, movies, music, books, notes, photo_tags, photo_albums, video_tags, video_uploads, events, groups, checkins
50
+
51
+ ### Publish Calls ###
52
+ **UNDER CONSTRUCTION FOR BETTER PUBLIC API**
53
+
54
+ All methods take options specified in the facebook api such as [Post](http://developers.facebook.com/docs/reference/api/post/#publishing)
55
+
56
+ publish!, note!, link!, event!, album!, checkin!
57
+
58
+ ### Permissions ###
59
+
60
+ fb_open_graph.has_permissions?(*permission_names_comma_separated)
61
+ will return true or false
62
+
63
+ # JavaScript #
64
+
65
+ You'll want something that looks like this in your view:
66
+
67
+ if Rails.env.test?
68
+ include_facebook_stub
69
+ else
70
+ javascript_include_tag '//connect.facebook.net/en_US/all.js#xfbml=1'
71
+ end
@@ -0,0 +1,38 @@
1
+ require 'uri'
2
+ require "digest/md5"
3
+ require 'open_graph/rails/action_controller_accessor'
4
+ require 'open_graph/rails/action_view_help'
5
+ require 'open_graph/fb_open_graph'
6
+
7
+ if defined?(RAILS_ENV) && RAILS_ENV == 'test'
8
+ require 'open_graph/test/facebook_stub'
9
+ end
10
+
11
+ module OpenGraph
12
+ def config
13
+ @config ||= begin
14
+ config = HashWithIndifferentAccess.new
15
+ yaml_file = YAML.load_file("#{RAILS_ROOT}/config/facebook.yml")
16
+ config.merge(yaml_file[RAILS_ENV])
17
+ end
18
+ end
19
+
20
+ def logger
21
+ @logger ||= begin
22
+ if defined?(::Rails.logger)
23
+ ::Rails.logger
24
+ elsif defined?(RAILS_DEFAULT_LOGGER)
25
+ RAILS_DEFAULT_LOGGER
26
+ end
27
+ end
28
+ end
29
+ module_function :config, :logger
30
+
31
+ end
32
+
33
+ if defined?(ActionController::Base)
34
+ ActionController::Base.send(:include, OpenGraph::Rails::ActionControllerAccessor)
35
+ end
36
+ if defined?(ActionView::Base)
37
+ ActionView::Base.send(:include, OpenGraph::Rails::ActionViewHelp)
38
+ end
@@ -0,0 +1,192 @@
1
+ module OpenGraph
2
+ class FBOpenGraph < Struct.new(:all_cookies)
3
+
4
+ def facebook_cookie
5
+ @facebook_cookie ||= begin
6
+ cookie = all_cookies["fbs_#{OpenGraph.config[:appid]}"]
7
+ validated_cookie(cookie)
8
+ end
9
+ end
10
+
11
+ def valid?
12
+ access_token.present?
13
+ end
14
+
15
+ def use_manual_session!(uid, access_token)
16
+ @uid = uid
17
+ @access_token = access_token
18
+ @manual = true
19
+ end
20
+
21
+ def access_token
22
+ @access_token ||= facebook_cookie['access_token'] unless @manual
23
+ @access_token || ''
24
+ end
25
+
26
+ def uid
27
+ @uid ||= facebook_cookie['uid'] unless @manual
28
+ @uid.blank? ? nil : @uid.to_i
29
+ end
30
+
31
+ # creates .news_feed(options)
32
+ # options for pagable_method
33
+ # :limit, :offset, :until, :since
34
+ # options for picture
35
+ # :type => (square|small|large)
36
+ # begin get methods
37
+ GRAPH_GET_METHODS = {
38
+ :info => nil,
39
+ :friends => :friends,
40
+ :news_feed => :home,
41
+ :profile_feed => :feed,
42
+ :likes => :likes,
43
+ :movies => :movies,
44
+ :music => :music,
45
+ :books => :books,
46
+ :notes => :notes,
47
+ :photo_tags => :photos,
48
+ :photo_albums => :albums,
49
+ :video_tags => :videos,
50
+ :video_uploads => :'videos/uploaded',
51
+ :events => :events,
52
+ :groups => :groups,
53
+ :checkins => :checkins,
54
+ :picture => :picture
55
+ }
56
+ defines = ""
57
+ GRAPH_GET_METHODS.each_pair do |method, connection_type|
58
+ defines << <<-METHOD
59
+ def #{method}(options={})
60
+ graph_get(options.merge(:connection_type => #{connection_type.inspect}, :requested_call => #{method.inspect}))
61
+ end
62
+ METHOD
63
+ end
64
+ eval(defines)
65
+
66
+ # end get methods
67
+ GRAPH_PUBLISH_METHODS = {
68
+ # profiles
69
+ :publish! => :feed,
70
+ :note! => :notes,
71
+ :link! => :links,
72
+ :event! => :events,
73
+ :album! => :albums,
74
+ :checkin! => :checkins,
75
+ }
76
+ GRAPH_PUBLISH_METHODS.each_pair do |method, connection_type|
77
+ defines << <<-METHOD
78
+ def #{method}(options={})
79
+ graph_post(options.merge(:connection_type => #{connection_type.inspect}))
80
+ end
81
+ METHOD
82
+ end
83
+ eval(defines)
84
+
85
+ def fql_query(table, field_names, new_uid = uid)
86
+ field_names = field_names.join(', ') if field_names.is_a?(Array)
87
+ query = "SELECT #{field_names} FROM #{table} WHERE uid = #{new_uid}"
88
+ fql_get(query)
89
+ end
90
+
91
+ def has_permissions?(permission_names)
92
+ response = fql_query('permissions', permission_names)
93
+ permission_hash = response.first
94
+ return false unless permission_hash.is_a?(Hash)
95
+
96
+ permission_names = permission_names.split(',').collect(&:strip) if permission_names.is_a?(String)
97
+ permission_names.each do |perm|
98
+ return false if permission_hash[perm] != 1
99
+ end
100
+ return true
101
+ end
102
+
103
+ private
104
+
105
+ def validated_cookie(cookie)
106
+ cookie = cookie.present? ? Rack::Utils.parse_query(cookie.gsub('"', '')) : nil
107
+ return {} unless cookie.present?
108
+ cookieness = cookie.except('sig').keys.sort.collect {|k| "#{k}=#{cookie[k]}"}.join
109
+ cookieness += OpenGraph.config[:secret]
110
+ calculated_sig = Digest::MD5.hexdigest(cookieness)
111
+ calculated_sig == cookie['sig'] ? cookie : {}
112
+ end
113
+
114
+ def fql_get(query)
115
+ options = {
116
+ :access_token => access_token,
117
+ :query => query,
118
+ :format => 'json'
119
+ }
120
+ HTTParty.get("https://api.facebook.com/method/fql.query#{query_string(options)}").parsed_response
121
+ end
122
+
123
+ def graph_post(options={})
124
+ return false unless valid?
125
+ options.symbolize_keys!.reverse_merge!(default_options)
126
+ url = build_url(options.dup)
127
+ HTTParty.post(url).parsed_response
128
+ end
129
+
130
+ def fb_cache(key, value=nil)
131
+ @cache ||= {}
132
+ if(value)
133
+ @cache[key] = value
134
+ else
135
+ @cache[key]
136
+ end
137
+ end
138
+
139
+ # options are :connection_type, :uid, :access_token
140
+ # + any facebook options
141
+ def graph_get(options={})
142
+ options.symbolize_keys!.reverse_merge!(default_options)
143
+ requested_call = options.delete(:requested_call)
144
+ url = build_url(options.dup)
145
+
146
+ return fb_cache(url) if fb_cache(url)
147
+
148
+ OpenGraph.logger.info("[OpenGraph] fetching: #{url}")
149
+ response = HTTParty.get(url).response
150
+ response_hash = parse_response(response)
151
+ if response.is_a?(Net::HTTPOK)
152
+ response_hash['location'] = fetch_codified_location(options.slice(:uid, :access_token)) if requested_call == :info
153
+ end
154
+ fb_cache(url, response_hash)
155
+ end
156
+
157
+ def default_options
158
+ {:uid => uid, :access_token => access_token}
159
+ end
160
+
161
+ def build_url(options)
162
+ url = "https://graph.facebook.com/#{options.delete(:uid)}"
163
+ if connection_type = options.delete(:connection_type)
164
+ url << "/#{connection_type}"
165
+ end
166
+ url << query_string(options)
167
+ url
168
+ end
169
+
170
+ def query_string(options)
171
+ options.present? ? "?#{options.collect {|k, v| "#{k}=#{CGI.escape(v)}"}.join('&')}" : ""
172
+ end
173
+
174
+ #Craptacular way to get location of user (deprecated FB call to old api) REPLACE AT SOME POINT!
175
+ def fetch_codified_location(options_for_fql)
176
+ OpenGraph.logger.info("[OpenGraph] DEPRICATED - fetching codified location")
177
+ fql_query('user', 'current_location').first['current_location']
178
+ end
179
+
180
+ def parse_response(response)
181
+ case response.content_type
182
+ when 'text/javascript'
183
+ JSON.parse(response.body)
184
+ when 'image/jpeg'
185
+ {:content_type => response.content_type, :image => response.body}
186
+ end
187
+ end
188
+
189
+ end
190
+
191
+
192
+ end
@@ -0,0 +1,9 @@
1
+ module OpenGraph
2
+ module Rails
3
+ module ActionControllerAccessor
4
+ def fb_open_graph
5
+ @fb_open_graph ||= OpenGraph::FBOpenGraph.new(cookies)
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,18 @@
1
+ module OpenGraph
2
+ module Rails
3
+ module ActionViewHelp
4
+ @@facebook_javascript_stub = nil
5
+ def include_facebook_stub
6
+ @@facebook_javascript_stub ||= begin
7
+ data = ''
8
+ f =File.open(File.join( File.dirname(__FILE__),"../../../", "facebook-stub/", "facebook-stub.js"))
9
+ f.each_line do |line|
10
+ data << line
11
+ end
12
+ f.close
13
+ javascript_tag data
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,97 @@
1
+ module OpenGraph
2
+ class FBOpenGraph
3
+ @@access_token = nil
4
+ @@uid = nil
5
+
6
+ BASE_INFO = {
7
+ "name" => "Gandalf The Grey",
8
+ "location" => {
9
+ "name" => "San Francisco, California",
10
+ "city" => "San Francisco",
11
+ "zip" => "",
12
+ "country" => "United States",
13
+ "id" => 114952118516947,
14
+ "state" => "California"
15
+ },
16
+ "timezone" => -8,
17
+ "gender" => "male",
18
+ "id" => "6013893",
19
+ "birthday" => "01/12/1987",
20
+ "last_name" => "Shafer",
21
+ "updated_time" => "2011-02-10T00:40:26+0000",
22
+ "verified" => true,
23
+ "locale" => "en_US",
24
+ "religion" => "Wikipedia",
25
+ "bio" => "The greatest thing you'll ever learn is just to love and be loved in return.\r\n\r\nIf hearing the name Sharon Salinger causes you physical pain and emotional trauma then we are friends.\r\n\r\nMy life has a great cast but I can't figure out the plot.",
26
+ "hometown" => { "name" => nil, "id" => "" },
27
+ "link" => "http://www.facebook.com/thomas.shafer",
28
+ "political" => "Liberal",
29
+ "email" => "gandalf@change.org",
30
+ "middle_name" => "'Growly Pants'",
31
+ "first_name" => "Thomas"
32
+ }
33
+
34
+ # class level methods for setting the responses you would like to get
35
+ class << self
36
+ def info_override!(key, value)
37
+ BASE_INFO[key.to_s] = value
38
+ end
39
+
40
+ def invalid!
41
+ @@access_token = ''
42
+ end
43
+
44
+ def valid!
45
+ @@access_token = 'fb_token'
46
+ end
47
+
48
+ def uid=(uid)
49
+ @@uid = uid
50
+ end
51
+
52
+ def access_token=(token)
53
+ @@access_token = token
54
+ end
55
+ end
56
+
57
+ def uid_with_testing
58
+ @@uid || uid_without_testing
59
+ end
60
+ alias_method_chain :uid, :testing
61
+
62
+ def access_token_with_testing
63
+ @@access_token || access_token_without_testing
64
+ end
65
+ alias_method_chain :access_token, :testing
66
+
67
+ defines = ''
68
+ GRAPH_GET_METHODS.merge(GRAPH_PUBLISH_METHODS).keys.send('-', [:friends, :info, :picture]).each do |method|
69
+ defines << <<-METHOD
70
+ def #{method}(*args)
71
+ raise "#{method} not stubbed!!"
72
+ end
73
+ METHOD
74
+ end
75
+ eval(defines)
76
+
77
+ def friends(*args)
78
+ return false unless valid?
79
+ {"data"=>
80
+ [{"name"=>"Michael Levin-Gesundheit", "id"=>"11160"},
81
+ {"name"=>"Eleanor Birrell", "id"=>"21139"},
82
+ {"name"=>"Clotilde Dedecker", "id"=>"24021"},
83
+ {"name"=>"Nancy Elizabeth Townsend", "id"=>"100001899260534"},
84
+ {"name"=>"Allba Zackson", "id"=>"100001938274584"}]}
85
+ end
86
+
87
+ def info(*args)
88
+ return false unless valid?
89
+ BASE_INFO
90
+ end
91
+
92
+ def picture(*args)
93
+ @picture_data ||= {:content_type => 'image/png', :image => File.read(File.dirname(__FILE__)+'/facebook_stub/picture.png')}
94
+ end
95
+
96
+ end
97
+ end
@@ -0,0 +1,3 @@
1
+ module OpenGraph
2
+ VERSION = "0.0.2"
3
+ end
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "open_graph/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "open_graph"
7
+ s.version = OpenGraph::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Change.org Engineering"]
10
+ s.email = ["engineering@change.org"]
11
+ s.homepage = "https://github.com/change/open_graph"
12
+ s.summary = %q{A ruby wrapper for the new facebook graph api}
13
+ s.description = %q{OpenGraph provides an easy to use wrapper for making facebook calls. It also provides javascript stubs allowing seemless testing against the javascript sdk.}
14
+
15
+ s.rubyforge_project = "open_graph"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+ end
metadata ADDED
@@ -0,0 +1,80 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: open_graph
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 2
10
+ version: 0.0.2
11
+ platform: ruby
12
+ authors:
13
+ - Change.org Engineering
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-02-23 00:00:00 -08:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: OpenGraph provides an easy to use wrapper for making facebook calls. It also provides javascript stubs allowing seemless testing against the javascript sdk.
23
+ email:
24
+ - engineering@change.org
25
+ executables: []
26
+
27
+ extensions: []
28
+
29
+ extra_rdoc_files: []
30
+
31
+ files:
32
+ - .gitignore
33
+ - .gitmodules
34
+ - Gemfile
35
+ - Rakefile
36
+ - Readme.md
37
+ - lib/open_graph.rb
38
+ - lib/open_graph/fb_open_graph.rb
39
+ - lib/open_graph/rails/action_controller_accessor.rb
40
+ - lib/open_graph/rails/action_view_help.rb
41
+ - lib/open_graph/test/facebook_stub.rb
42
+ - lib/open_graph/test/facebook_stub/picture.png
43
+ - lib/open_graph/version.rb
44
+ - open_graph.gemspec
45
+ has_rdoc: true
46
+ homepage: https://github.com/change/open_graph
47
+ licenses: []
48
+
49
+ post_install_message:
50
+ rdoc_options: []
51
+
52
+ require_paths:
53
+ - lib
54
+ required_ruby_version: !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ hash: 3
60
+ segments:
61
+ - 0
62
+ version: "0"
63
+ required_rubygems_version: !ruby/object:Gem::Requirement
64
+ none: false
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ hash: 3
69
+ segments:
70
+ - 0
71
+ version: "0"
72
+ requirements: []
73
+
74
+ rubyforge_project: open_graph
75
+ rubygems_version: 1.5.0
76
+ signing_key:
77
+ specification_version: 3
78
+ summary: A ruby wrapper for the new facebook graph api
79
+ test_files: []
80
+