mini_fb 0.1.1
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/README.markdown +38 -0
- data/lib/mini_fb.rb +204 -0
- data/test/mini_fb_tests.rb +22 -0
- metadata +56 -0
data/README.markdown
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
MiniFB - the simple miniature facebook library
|
2
|
+
==============================================
|
3
|
+
|
4
|
+
MiniFB is a small, lightweight Ruby library for interacting with the [Facebook API](http://wiki.developers.facebook.com/index.php/API).
|
5
|
+
|
6
|
+
General Usage
|
7
|
+
-------------
|
8
|
+
|
9
|
+
The most general case is to use MiniFB.call method:
|
10
|
+
|
11
|
+
user_hash = MiniFB.call(FB_API_KEY, FB_SECRET, "Users.getInfo", "session_key"=>@session_key, "uids"=>@uid, "fields"=>User.all_fields)
|
12
|
+
|
13
|
+
Which simply returns the parsed json response from Facebook.
|
14
|
+
|
15
|
+
Some Higher Level Objects for Common Uses
|
16
|
+
----------------------
|
17
|
+
|
18
|
+
Get a MiniFB::Session:
|
19
|
+
|
20
|
+
@fb = MiniFB::Session.new(FB_API_KEY, FB_SECRET, @fb_session, @fb_uid)
|
21
|
+
|
22
|
+
With the session, you can then get the user information for the session/uid.
|
23
|
+
|
24
|
+
user = @fb.user
|
25
|
+
|
26
|
+
Then get info from the user:
|
27
|
+
|
28
|
+
first_name = user["first_name"]
|
29
|
+
|
30
|
+
Or profile photos:
|
31
|
+
|
32
|
+
photos = user.profile_photos
|
33
|
+
|
34
|
+
Or if you want other photos, try:
|
35
|
+
|
36
|
+
photos = @fb.photos("pids"=>[12343243,920382343,9208348])
|
37
|
+
|
38
|
+
|
data/lib/mini_fb.rb
ADDED
@@ -0,0 +1,204 @@
|
|
1
|
+
module MiniFB
|
2
|
+
require 'digest/md5'
|
3
|
+
require 'erb'
|
4
|
+
require 'json/pure'
|
5
|
+
|
6
|
+
# Global constants
|
7
|
+
FB_URL = "http://api.facebook.com/restserver.php"
|
8
|
+
FB_API_VERSION = "1.0"
|
9
|
+
|
10
|
+
class FaceBookError < StandardError
|
11
|
+
# Error that happens during a facebook call.
|
12
|
+
def initialize( error_code, error_msg )
|
13
|
+
raise StandardError.new( "Facebook error #{error_code}: #{error_msg}" )
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class Session
|
18
|
+
attr_accessor :api_key, :secret_key, :session_key, :uid
|
19
|
+
|
20
|
+
|
21
|
+
def initialize(api_key, secret_key, session_key, uid)
|
22
|
+
@api_key = api_key
|
23
|
+
@secret_key = FaceBookSecret.new secret_key
|
24
|
+
@session_key = session_key
|
25
|
+
@uid = uid
|
26
|
+
end
|
27
|
+
|
28
|
+
# returns current user
|
29
|
+
def user
|
30
|
+
return @user unless @user.nil?
|
31
|
+
@user = User.new(MiniFB.call(@api_key, @secret_key, "Users.getInfo", "session_key"=>@session_key, "uids"=>@uid, "fields"=>User.all_fields)[0], self)
|
32
|
+
@user
|
33
|
+
end
|
34
|
+
|
35
|
+
def photos
|
36
|
+
Photos.new(self)
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
end
|
41
|
+
class User
|
42
|
+
FIELDS = [:uid, :status, :political, :pic_small, :name, :quotes, :is_app_user, :tv, :profile_update_time, :meeting_sex, :hs_info, :timezone, :relationship_status, :hometown_location, :about_me, :wall_count, :significant_other_id, :pic_big, :music, :work_history, :sex, :religion, :notes_count, :activities, :pic_square, :movies, :has_added_app, :education_history, :birthday, :birthday_date, :first_name, :meeting_for, :last_name, :interests, :current_location, :pic, :books, :affiliations, :locale, :profile_url, :proxied_email, :email_hashes, :allowed_restrictions, :pic_with_logo, :pic_big_with_logo, :pic_small_with_logo, :pic_square_with_logo]
|
43
|
+
STANDARD_FIELDS = [:uid, :first_name, :last_name, :name, :timezone, :birthday, :sex, :affiliations, :locale, :profile_url, :proxied_email]
|
44
|
+
|
45
|
+
def self.all_fields
|
46
|
+
FIELDS.join(",")
|
47
|
+
end
|
48
|
+
|
49
|
+
def initialize(fb_hash, session)
|
50
|
+
@fb_hash = fb_hash
|
51
|
+
@session = session
|
52
|
+
end
|
53
|
+
|
54
|
+
def [](key)
|
55
|
+
@fb_hash[key]
|
56
|
+
end
|
57
|
+
|
58
|
+
def uid
|
59
|
+
return self["uid"]
|
60
|
+
end
|
61
|
+
|
62
|
+
def profile_photos
|
63
|
+
@session.photos.get("uid"=>uid, "aid"=>profile_pic_album_id)
|
64
|
+
end
|
65
|
+
|
66
|
+
def profile_pic_album_id
|
67
|
+
merge_aid(-3, uid)
|
68
|
+
end
|
69
|
+
|
70
|
+
def merge_aid(aid, uid)
|
71
|
+
uid = uid.to_i
|
72
|
+
ret = (uid << 32) + (aid & 0xFFFFFFFF)
|
73
|
+
# puts 'merge_aid=' + ret.inspect
|
74
|
+
return ret
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
class Photos
|
79
|
+
|
80
|
+
def initialize(session)
|
81
|
+
@session = session
|
82
|
+
end
|
83
|
+
|
84
|
+
def get(params)
|
85
|
+
pids = params["pids"]
|
86
|
+
if !pids.nil? && pids.is_a?(Array)
|
87
|
+
pids = pids.join(",")
|
88
|
+
params["pids"] = pids
|
89
|
+
end
|
90
|
+
MiniFB.call(@session.api_key, @session.secret_key, "photos.get", params.update("session_key"=>@session.session_key))
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# Call facebook server with a method request. Most keyword arguments
|
95
|
+
# are passed directly to the server with a few exceptions.
|
96
|
+
# The 'sig' value will always be computed automatically.
|
97
|
+
# The 'v' version will be supplied automatically if needed.
|
98
|
+
# The 'call_id' defaults to True, which will generate a valid
|
99
|
+
# number. Otherwise it should be a valid number or False to disable.
|
100
|
+
|
101
|
+
# The default return is a parsed json object.
|
102
|
+
# Unless the 'format' and/or 'callback' arguments are given,
|
103
|
+
# in which case the raw text of the reply is returned. The string
|
104
|
+
# will always be returned, even during errors.
|
105
|
+
|
106
|
+
# If an error occurs, a FacebookError exception will be raised
|
107
|
+
# with the proper code and message.
|
108
|
+
|
109
|
+
# The secret argument should be an instance of FacebookSecret
|
110
|
+
# to hide value from simple introspection.
|
111
|
+
def MiniFB.call( api_key, secret, method, kwargs )
|
112
|
+
|
113
|
+
puts 'kwargs=' + kwargs.inspect
|
114
|
+
|
115
|
+
# Prepare arguments for call
|
116
|
+
call_id = kwargs.fetch("call_id", true)
|
117
|
+
if call_id == true then
|
118
|
+
kwargs["call_id"] = Time.now.tv_sec.to_s
|
119
|
+
else
|
120
|
+
kwargs.delete("call_id")
|
121
|
+
end
|
122
|
+
|
123
|
+
custom_format = kwargs.include?("format") or kwargs.include?("callback")
|
124
|
+
kwargs["format"] ||= "JSON"
|
125
|
+
kwargs["v"] ||= FB_API_VERSION
|
126
|
+
kwargs["api_key"]||= api_key
|
127
|
+
kwargs["method"] ||= method
|
128
|
+
|
129
|
+
# Hash with secret
|
130
|
+
arg_string = String.new
|
131
|
+
kwargs.sort.each { |kv| arg_string << kv[0] << "=" << kv[1].to_s }
|
132
|
+
kwargs["sig"] = Digest::MD5.hexdigest( arg_string + secret.value.call )
|
133
|
+
|
134
|
+
# Call website with POST request
|
135
|
+
begin
|
136
|
+
response = Net::HTTP.post_form( URI.parse(FB_URL), kwargs )
|
137
|
+
rescue SocketError => err
|
138
|
+
raise IOError.new( "Cannot connect to the facebook server: " + err )
|
139
|
+
end
|
140
|
+
|
141
|
+
# Handle response
|
142
|
+
return response.body if custom_format
|
143
|
+
|
144
|
+
data = JSON.parse( response.body )
|
145
|
+
puts 'response=' + data.inspect
|
146
|
+
if data.include?( "error_msg" ) then
|
147
|
+
raise FaceBookError.new( data["error_code"] || 1, data["error_msg"] )
|
148
|
+
end
|
149
|
+
return data
|
150
|
+
end
|
151
|
+
|
152
|
+
|
153
|
+
# This function expects arguments as a hash, so
|
154
|
+
# it is agnostic to different POST handling variants in ruby.
|
155
|
+
#
|
156
|
+
# Validate the arguments received from facebook. This is usually
|
157
|
+
# sent for the iframe in Facebook's canvas. It is not necessary
|
158
|
+
# to use this on the auth_token and uid passed to callbacks like
|
159
|
+
# post-add and post-remove.
|
160
|
+
#
|
161
|
+
# The arguments must be a mapping of to string keys and values
|
162
|
+
# or a string of http request data.
|
163
|
+
#
|
164
|
+
# If the data is invalid or not signed properly, and empty
|
165
|
+
# dictionary is returned.
|
166
|
+
#
|
167
|
+
# The secret argument should be an instance of FacebookSecret
|
168
|
+
# to hide value from simple introspection.
|
169
|
+
#
|
170
|
+
def MiniFB.validate( secret, arguments )
|
171
|
+
|
172
|
+
signature = arguments.delete( "fb_sig" )
|
173
|
+
return arguments if signature.nil?
|
174
|
+
|
175
|
+
unsigned = Hash.new
|
176
|
+
signed = Hash.new
|
177
|
+
|
178
|
+
arguments.each do |k, v|
|
179
|
+
if k =~ /^fb_sig_(.*)/ then
|
180
|
+
signed[$1] = v
|
181
|
+
else
|
182
|
+
unsigned[k] = v
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
arg_string = String.new
|
187
|
+
signed.sort.each { |kv| arg_string << kv[0] << "=" << kv[1] }
|
188
|
+
if Digest::MD5.hexdigest( arg_string + secret ) != signature then
|
189
|
+
unsigned # Hash is incorrect, return only unsigned fields.
|
190
|
+
else
|
191
|
+
unsigned.merge signed
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
class FaceBookSecret
|
196
|
+
# Simple container that stores a secret value.
|
197
|
+
# Proc cannot be dumped or introspected by normal tools.
|
198
|
+
attr_reader :value
|
199
|
+
|
200
|
+
def initialize( value )
|
201
|
+
@value = Proc.new { value }
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
metadata
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mini_fb
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Travis Reeder
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-10-11 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: Tiny facebook library
|
17
|
+
email: travis@appoxy.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README.markdown
|
24
|
+
files:
|
25
|
+
- lib/mini_fb.rb
|
26
|
+
- README.markdown
|
27
|
+
has_rdoc: true
|
28
|
+
homepage: http://github.com/appoxy/mini_fb
|
29
|
+
licenses: []
|
30
|
+
|
31
|
+
post_install_message:
|
32
|
+
rdoc_options:
|
33
|
+
- --charset=UTF-8
|
34
|
+
require_paths:
|
35
|
+
- lib
|
36
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: "0"
|
41
|
+
version:
|
42
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: "0"
|
47
|
+
version:
|
48
|
+
requirements: []
|
49
|
+
|
50
|
+
rubyforge_project:
|
51
|
+
rubygems_version: 1.3.5
|
52
|
+
signing_key:
|
53
|
+
specification_version: 3
|
54
|
+
summary: Tiny facebook library
|
55
|
+
test_files:
|
56
|
+
- test/mini_fb_tests.rb
|