Class: Mogli::Client

Inherits:
Object
  • Object
show all
Includes:
HTTParty, Event, User
Defined in:
lib/mogli/client.rb,
lib/mogli/client/user.rb,
lib/mogli/client/event.rb

Direct Known Subclasses

AppClient

Defined Under Namespace

Modules: Event, User Classes: ClientException, FeedActionRequestLimitExceeded, HTTPException, OAuthAccessTokenException, OAuthException, OAuthUnauthorizedClientException, QueryParseException, SessionInvalidatedDueToPasswordChange, UnrecognizeableClassError

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from User

#user

Methods included from Event

#event

Constructor Details

#initialize(access_token = nil, expiration = nil) ⇒ Client

Returns a new instance of Client.



37
38
39
40
41
42
43
# File 'lib/mogli/client.rb', line 37

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

Instance Attribute Details

#access_tokenObject (readonly)

Returns the value of attribute access_token.



6
7
8
# File 'lib/mogli/client.rb', line 6

def access_token
  @access_token
end

#default_paramsObject (readonly)

Returns the value of attribute default_params.



7
8
9
# File 'lib/mogli/client.rb', line 7

def default_params
  @default_params
end

#expirationObject (readonly)

Returns the value of attribute expiration.



8
9
10
# File 'lib/mogli/client.rb', line 8

def expiration
  @expiration
end

Class Method Details

.access_token_from_access_data(access_data) ⇒ Object



96
97
98
99
# File 'lib/mogli/client.rb', line 96

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) ⇒ Object



106
107
108
109
110
111
112
# File 'lib/mogli/client.rb', line 106

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) ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/mogli/client.rb', line 49

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) ⇒ Object



90
91
92
93
94
# File 'lib/mogli/client.rb', line 90

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) ⇒ Object



101
102
103
104
# File 'lib/mogli/client.rb', line 101

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

.raise_client_exception(post_data) ⇒ Object



69
70
71
# File 'lib/mogli/client.rb', line 69

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) ⇒ Object



73
74
75
76
77
78
79
80
81
82
83
# File 'lib/mogli/client.rb', line 73

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) ⇒ Boolean

Returns:

  • (Boolean)


85
86
87
88
# File 'lib/mogli/client.rb', line 85

def self.response_is_error?(post_data)
   post_data.kind_of?(Hash) and
   !post_data["error"].empty?
end

Instance Method Details

#api_path(path) ⇒ Object



25
26
27
# File 'lib/mogli/client.rb', line 25

def api_path(path)
  "https://graph.facebook.com/#{path}"
end

#capitalize_if_required(string) ⇒ Object



200
201
202
# File 'lib/mogli/client.rb', line 200

def capitalize_if_required(string)
  string.downcase == string ? string.capitalize : string
end

#constantize_string(klass) ⇒ Object



204
205
206
# File 'lib/mogli/client.rb', line 204

def constantize_string(klass)
  klass.is_a?(String) ? Mogli.const_get(capitalize_if_required(klass)) : klass
end

#create_instance(klass, data) ⇒ Object



192
193
194
195
196
197
198
# File 'lib/mogli/client.rb', line 192

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) ⇒ Object



119
120
121
# File 'lib/mogli/client.rb', line 119

def delete(path)
  self.class.delete(api_path(path),:query=>default_params)
end

#determine_class(klass_or_klasses, data) ⇒ Object



208
209
210
211
212
# File 'lib/mogli/client.rb', line 208

def determine_class(klass_or_klasses,data)
  return constantize_string(data['type']) if data.key?('type') && klass_or_klasses == Mogli::Model
  klasses = Array(klass_or_klasses).map { |k| constantize_string(k)}
  klasses.detect {|klass| klass.recognize?(data)} || klasses.first
end

#expired?Boolean

Returns:

  • (Boolean)


45
46
47
# File 'lib/mogli/client.rb', line 45

def expired?
  expiration and expiration < Time.now
end

#extract_fetching_array(hash, klass) ⇒ Object



171
172
173
174
175
176
177
178
179
180
181
# File 'lib/mogli/client.rb', line 171

def extract_fetching_array(hash,klass)
  f = Mogli::FetchingArray.new
  f.concat(hash["data"])
  f.client = self
  f.classes = Array(klass)
  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) ⇒ Object

protected



159
160
161
162
163
164
165
# File 'lib/mogli/client.rb', line 159

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 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)
  return hash_or_array
end

#fields_to_serializeObject



223
224
225
# File 'lib/mogli/client.rb', line 223

def fields_to_serialize
  [:access_token,:default_params,:expiration]
end

#fql_multiquery(queries) ⇒ Object



134
135
136
137
# File 'lib/mogli/client.rb', line 134

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_pathObject



33
34
35
# File 'lib/mogli/client.rb', line 33

def fql_multiquery_path
  "https://api.facebook.com/method/fql.multiquery"
end

#fql_pathObject



29
30
31
# File 'lib/mogli/client.rb', line 29

def fql_path
  "https://api.facebook.com/method/fql.query"
end

#fql_query(query, klass = nil, format = "json") ⇒ Object



128
129
130
131
132
# File 'lib/mogli/client.rb', line 128

def fql_query(query,klass=nil,format="json")
  data = self.class.post(fql_path,:body=>default_params.merge({:query=>query,:format=>format}))
  return data unless format=="json"
  map_data(data,klass)
end

#get_and_map(path, klass = nil, body_args = {}) ⇒ Object



139
140
141
142
143
# File 'lib/mogli/client.rb', line 139

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 = {}) ⇒ Object



145
146
147
148
# File 'lib/mogli/client.rb', line 145

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) ⇒ Boolean

Returns:

  • (Boolean)


167
168
169
# File 'lib/mogli/client.rb', line 167

def is_fetching_array?(hash)
  hash.has_key?("data") and hash["data"].instance_of?(Array)
end

#map_data(data, klass = nil) ⇒ Object



150
151
152
153
154
155
# File 'lib/mogli/client.rb', line 150

def map_data(data,klass=nil)
  raise_error_if_necessary(data)
  hash_or_array = extract_hash_or_array(data,klass)
  hash_or_array = map_to_class(hash_or_array,klass) if klass
  hash_or_array
end

#map_to_class(hash_or_array, klass) ⇒ Object



183
184
185
186
187
188
189
190
# File 'lib/mogli/client.rb', line 183

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

#marshal_dumpObject

Only serialize the bare minimum to recreate the session.



233
234
235
# File 'lib/mogli/client.rb', line 233

def marshal_dump#:nodoc:
  fields_to_serialize.map{|field| send(field)}
end

#marshal_load(variables) ⇒ Object

Only serialize the bare minimum to recreate the session.



228
229
230
# File 'lib/mogli/client.rb', line 228

def marshal_load(variables)#:nodoc:
  fields_to_serialize.each_with_index{|field, index| instance_variable_set("@#{field}", variables[index])}
end

#post(path, klass, body_args) ⇒ Object



114
115
116
117
# File 'lib/mogli/client.rb', line 114

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) ⇒ Object

Raises:



214
215
216
217
218
219
220
221
# File 'lib/mogli/client.rb', line 214

def raise_error_if_necessary(data)
  raise HTTPException if data.respond_to?(:code) and data.code != 200
  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
end

#subscribe_to_model(model, options) ⇒ Object



123
124
125
126
# File 'lib/mogli/client.rb', line 123

def subscribe_to_model(model,options)
  options_to_send=options.dup
  self.class.post("http://")
end

#to_yaml(opts = {}) ⇒ Object

Only serialize the bare minimum to recreate the session.



238
239
240
241
242
243
244
245
246
# File 'lib/mogli/client.rb', line 238

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