class Mogli::Client

Attributes

access_token[R]
default_params[R]
expiration[R]

Public Class Methods

access_token_from_access_data(access_data) click to toggle source
# File lib/mogli/client.rb, line 98
def self.access_token_from_access_data(access_data)
  return nil if access_data.nil?
  access_data['access_token']
end
create_and_authenticate_as_application(client_id, secret) click to toggle source
# File lib/mogli/client.rb, line 108
def self.create_and_authenticate_as_application(client_id, secret)
  authenticator = Mogli::Authenticator.new(client_id, secret, nil)
  access_data = authenticator.get_access_token_for_application
  client = AppClient.new(access_data)
  client.application_id = client_id
  client
end
create_from_code_and_authenticator(code,authenticator) click to toggle source
# File lib/mogli/client.rb, line 51
def self.create_from_code_and_authenticator(code,authenticator)
  post_data = get(authenticator.access_token_url(code)).parsed_response
  if (response_is_error?(post_data))
    raise_client_exception(post_data)
  end
  parts = post_data.split("&")
  hash = {}
  parts.each do |p| (k,v) = p.split("=")
    hash[k]=CGI.unescape(v)
  end

  if hash["expires"]
    expires = Time.now.to_i + hash["expires"].to_i
  else
    expires = nil
  end

  new(hash["access_token"],expires)
end
create_from_session_key(session_key, client_id, secret) click to toggle source
# File lib/mogli/client.rb, line 92
def self.create_from_session_key(session_key, client_id, secret)
  authenticator = Mogli::Authenticator.new(client_id, secret, nil)
  access_data = authenticator.get_access_token_for_session_key(session_key)
  new(access_token_from_access_data(access_data),expiration_from_access_data(access_data))
end
expiration_from_access_data(access_data) click to toggle source
# File lib/mogli/client.rb, line 103
def self.expiration_from_access_data(access_data)
  return nil if access_data.nil? or access_data['expires'].nil?
  Time.now.to_i + access_data['expires'].to_i
end
new(access_token = nil,expiration=nil) click to toggle source
# File lib/mogli/client.rb, line 39
def initialize(access_token = nil,expiration=nil)
  @access_token = access_token
  # nil expiration means extended access
  expiration = Time.now.to_i + 10*365*24*60*60 if expiration.nil? or expiration == 0
  @expiration = Time.at(expiration)
  @default_params = @access_token ? {:access_token=>access_token} : {}
end
raise_client_exception(post_data) click to toggle source
# File lib/mogli/client.rb, line 71
def self.raise_client_exception(post_data)
  raise_error_by_type_and_message(post_data["error"]["type"], post_data["error"]["message"])
end
raise_error_by_type_and_message(type, message) click to toggle source
# File lib/mogli/client.rb, line 75
def self.raise_error_by_type_and_message(type, message)
  if type == 'OAuthException' && message =~ /Feed action request limit reached/
    raise FeedActionRequestLimitExceeded.new(message)
  elsif type == 'OAuthException' && message =~ /The session has been invalidated because the user has changed the password/
    raise SessionInvalidatedDueToPasswordChange.new(message)
  elsif Mogli::Client.const_defined?(type)
    raise Mogli::Client.const_get(type).new(message)
  else
    raise ClientException.new("#{type}: #{message}")
  end
end
response_is_error?(post_data) click to toggle source
# File lib/mogli/client.rb, line 87
def self.response_is_error?(post_data)
   post_data.kind_of?(Hash) and
   !post_data["error"].empty?
end

Public Instance Methods

api_path(path) click to toggle source
# File lib/mogli/client.rb, line 27
def api_path(path)
  "https://graph.facebook.com/#{path}"
end
capitalize_if_required(string) click to toggle source
# File lib/mogli/client.rb, line 223
def capitalize_if_required(string)
  string.downcase == string ? string.capitalize : string
end
constantize_string(klass) click to toggle source
# File lib/mogli/client.rb, line 227
def constantize_string(klass)
  klass.is_a?(String) ? Mogli.const_get(capitalize_if_required(klass)) : klass
end
create_instance(klass,data) click to toggle source
# File lib/mogli/client.rb, line 215
def create_instance(klass,data)
  klass_to_create =  determine_class(klass,data)
  if klass_to_create.nil?
    raise UnrecognizeableClassError.new("unable to recognize klass for #{klass.inspect} => #{data.inspect}")
  end
  klass_to_create.new(data,self)
end
delete(path) click to toggle source
# File lib/mogli/client.rb, line 132
def delete(path)
  self.class.delete(api_path(path),:query=>default_params)
end
determine_class(klass_or_klasses,data) click to toggle source
# File lib/mogli/client.rb, line 231
def determine_class(klass_or_klasses,data)
  if data.respond_to?(:has_key?) && data.has_key?('type') &&
                                     klass_or_klasses == Mogli::Model
    return constantize_string(data['type'])
  end
  klasses = Array(klass_or_klasses).map { |k| constantize_string(k)}
  klasses.detect {|klass| klass.recognize?(data)} || klasses.first
end
exchange_access_token(client_id, secret) click to toggle source
# File lib/mogli/client.rb, line 121
def exchange_access_token(client_id, secret)
  authenticator = Mogli::Authenticator.new(client_id, secret, nil)
  results = authenticator.extend_access_token(@access_token)
  self.class.new(results["access_token"],Time.now.to_i+results["expires"].to_i)
end
expired?() click to toggle source
# File lib/mogli/client.rb, line 47
def expired?
  expiration and expiration < Time.now
end
extended?() click to toggle source
# File lib/mogli/client.rb, line 116
def extended?
  (expiration.to_i - Time.now.to_i) > 24*60*60

end
extract_fetching_array(hash,klass) click to toggle source
# File lib/mogli/client.rb, line 193
def extract_fetching_array(hash,klass)
  f = Mogli::FetchingArray.new
  f.concat(hash["data"])
  f.client = self
  f.classes = Array(klass)
  f.total_count = hash["count"]
  if paging=hash["paging"]
    f.next_url = URI.encode paging["next"] unless paging["next"].nil?
    f.previous_url = URI.encode paging["previous"] unless paging["previous"].nil?
  end
  f
end
extract_hash_or_array(hash_or_array,klass) click to toggle source

protected

# File lib/mogli/client.rb, line 177
def extract_hash_or_array(hash_or_array,klass)
  hash_or_array = hash_or_array.parsed_response if hash_or_array.respond_to?(:parsed_response)
  return nil if hash_or_array == false
  return []  if hash_or_array == {"count" => 0}
  return hash_or_array if hash_or_array.nil? or hash_or_array.kind_of?(Array)
  return extract_fetching_array(hash_or_array,klass) if is_fetching_array?(hash_or_array)
  # Facebook doesn't return numbers or booleans in an object or list
  # container; this will catch the number, "true" and "false" response case
  return hash_or_array
end
fields_to_serialize() click to toggle source
# File lib/mogli/client.rb, line 249
def fields_to_serialize
  [:access_token,:default_params,:expiration]
end
fql_multiquery(queries) click to toggle source
# File lib/mogli/client.rb, line 147
def fql_multiquery(queries)
  data = self.class.post(fql_multiquery_path,:body=>default_params.merge({:queries=>queries.to_json,:format=>"json"}))
  map_data(data)
end
fql_multiquery_path() click to toggle source
# File lib/mogli/client.rb, line 35
def fql_multiquery_path
  "https://api.facebook.com/method/fql.multiquery"
end
fql_path() click to toggle source
# File lib/mogli/client.rb, line 31
def fql_path
  "https://graph.facebook.com/fql"
end
fql_query(query,klass=nil,format="json") click to toggle source
# File lib/mogli/client.rb, line 141
def fql_query(query,klass=nil,format="json")
  data = self.class.get(fql_path,:query=>default_params.merge({:q=>query,:format=>format})).parsed_response
  return data unless format=="json"
  map_data(data["data"],klass)
end
get_and_map(path,klass=nil,body_args = {}) click to toggle source
# File lib/mogli/client.rb, line 152
def get_and_map(path,klass=nil,body_args = {})
  data = self.class.get(api_path(path),:query=>default_params.merge(body_args))
  data = data.values if body_args.key?(:ids) && !data.key?('error')
  map_data(data,klass)
end
get_and_map_url(url,klass=nil,body_args = {}) click to toggle source
# File lib/mogli/client.rb, line 158
def get_and_map_url(url,klass=nil,body_args = {})
  data = self.class.get(url,:query=>default_params.merge(body_args))
  map_data(data,klass)
end
is_fetching_array?(hash) click to toggle source
# File lib/mogli/client.rb, line 188
def is_fetching_array?(hash)
  return false unless hash.respond_to? :has_key?
  hash.has_key?("data") and hash["data"].instance_of?(Array)
end
map_data(data,klass=nil) click to toggle source
# File lib/mogli/client.rb, line 163
def map_data(data,klass=nil)
  raise_error_if_necessary(data)
  hash_or_array = extract_hash_or_array(data,klass)
  if hash_or_array.is_a?(Array) && hash_or_array.size == 2 && hash_or_array[1].is_a?(Hash) && hash_or_array[1]['body']
      # responses from batch queries are buried inside a
      # completely different data structure
      hash_or_array = JSON.parse(hash_or_array[1]['body'].first).values
  end
  hash_or_array = map_to_class(hash_or_array,klass) if klass
  hash_or_array
end
map_to_class(hash_or_array,klass) click to toggle source
# File lib/mogli/client.rb, line 206
def map_to_class(hash_or_array,klass)
  return nil if !hash_or_array
  if hash_or_array.kind_of?(Array)
    hash_or_array.map! {|i| create_instance(klass,i)}
  else
    hash_or_array = create_instance(klass,hash_or_array)
  end
end
post(path,klass,body_args) click to toggle source
# File lib/mogli/client.rb, line 127
def post(path,klass,body_args)
  data = self.class.post(api_path(path),:body=>default_params.merge(body_args))
  map_data(data,klass)
end
raise_error_if_necessary(data) click to toggle source
# File lib/mogli/client.rb, line 240
def raise_error_if_necessary(data)
  if data.kind_of?(Hash)
    if data.keys.size == 1 and data["error"]
      self.class.raise_error_by_type_and_message(data["error"]["type"], data["error"]["message"])
    end
  end
  raise HTTPException if data.respond_to?(:code) and data.code != 200 and data.code != 400
end
subscribe_to_model(model,options) click to toggle source
# File lib/mogli/client.rb, line 136
def subscribe_to_model(model,options)
  options_to_send=options.dup
  self.class.post("http://")
end
to_yaml( opts = {} ) click to toggle source

Only serialize the bare minimum to recreate the session.

# File lib/mogli/client.rb, line 264
def to_yaml( opts = {} )#nodoc
  YAML::quick_emit(self.object_id, opts) do |out|
    out.map(taguri) do |map|
      fields_to_serialize.each do |field|
        map.add(field, send(field))
      end
    end
  end
end