/usr/lib/ruby/1.8/ramaze/contrib/facebook/facebook.rb is in libramaze-ruby1.8 2010.06.18-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | require 'rubygems'
require 'socket'
require 'digest'
require 'json'
require 'cgi'
module Facebook
class Error < StandardError
end
class APIProxy
instance_methods.each { |m| undef_method m unless m =~ /^__/ }
def initialize name, client
@name, @client = name, client
end
def method_missing method, opts = {}
@client.call "#{@name}.#{method}", opts
end
end
class Client
include Ramaze::Trinity if defined? Ramaze
def initialize keepalive = true
@keepalive = keepalive
@proxies = {}
end
%w[ auth fbml feed fql friends notifications profile users pages events groups photos marketplace ].each do |n|
define_method(n){ @proxies[n] ||= APIProxy.new(n, self) }
end
def call method, opts = {}
args = { :api_key => KEY,
:call_id => Time.now.to_f,
:format => 'JSON',
:v => '1.0',
:session_key => params[:session_key] || SESSION,
:method => method }.merge(opts).map{ |k,v|
"#{k}=" + case v
when Hash
v.to_json
when Array
v.join(',')
else
v.to_s
end
}.sort
data = Array["sig=#{Digest::MD5.hexdigest(args.join+SECRET)}", *args].join('&')
begin
ret = post(data)
rescue Errno::ECONNRESET, Errno::EPIPE
@server = connect
retry
end while ret.empty? and @server = connect
ret = case
when ret == 'true'; true
when ret == 'false'; false
when ret[0..0] == '"'; ret[1..-2]
else
begin
JSON::parse(ret)
rescue JSON::ParserError
puts "Error parsing #{ret.inspect}"
raise
end
end
unless method == 'fql.query'
ret = ret.first if ret.is_a? Array and ret.size == 1 and ret.first.is_a? Hash
end
raise Facebook::Error, ret['error_msg'] if ret.is_a? Hash and ret['error_code']
ret
ensure
unless @keepalive
@server.close
@server = nil
end
end
def valid?
return false unless respond_to?(:request) and not request['fb_sig'].nil?
request['facebook.valid?'] ||= \
request['fb_sig'] == Digest::MD5.hexdigest(request.params.map{|k,v| "#{$1}=#{v}" if k =~ /^fb_sig_(.+)$/ }.compact.sort.join+SECRET)
end
def [] key
params[key]
end
def redirect url
url[0,0] = URL unless url =~ /^http/
if respond_to?(:response)
response.build "<fb:redirect url='#{url}'/>"
throw :respond
else
"<fb:redirect url='#{url}'/>"
end
end
def addurl goto = '/'
"http://apps.facebook.com/add.php?api_key=#{KEY}&next=#{CGI.escape '?next='+goto}"
end
def params
return {} unless valid?
request['facebook'] ||= \
request.params.inject({}) { |h,(k,v)|
next h unless k =~ /^fb_sig_(.+)$/
k = $1.to_sym
case k.to_s
when 'friends'
h[k] = v.split(',').map{|e|e.to_i}
when /time$/
h[k] = Time.at(v.to_f)
when 'expires'
v = v.to_i
h[k] = v>0 ? Time.at(v) : v
when 'user'
h[k] = v.to_i
when /^(position_|in_|is_|added)/
h[k] = v=='1'
else
h[k] = v
end
h
}
end
private
def connect
@socket.close if @socket
TCPSocket.new('api.facebook.com', 80)
end
def post data
@server ||= connect
@server.puts "POST /restserver.php HTTP/1.1\r\n"
@server.puts "Host: api.facebook.com\r\n"
@server.puts "Connection: keep-alive\r\n" if @keepalive
@server.puts "Content-Type: application/x-www-form-urlencoded\r\n"
@server.puts "Content-Length: #{data.length}\r\n"
@server.puts "\r\n#{data}\r\n"
@server.puts "\r\n\r\n"
buf = ''
while @server.gets
if $_ == "\r\n"
@server.gets
if $_.strip! == '0'
@server.gets
break
end
buf << @server.read($_.to_i(16))
end
end
buf
end
end
end
|