facebooker 1.0.18 → 1.0.29

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/{History.txt → CHANGELOG.rdoc} +0 -0
  2. data/{COPYING → COPYING.rdoc} +0 -0
  3. data/{README.txt → README.rdoc} +11 -4
  4. data/Rakefile +18 -15
  5. data/{TODO.txt → TODO.rdoc} +0 -0
  6. data/generators/facebook/templates/config/facebooker.yml +3 -0
  7. data/init.rb +12 -61
  8. data/lib/facebooker.rb +22 -15
  9. data/lib/facebooker/adapters/adapter_base.rb +3 -0
  10. data/lib/facebooker/logging.rb +1 -1
  11. data/lib/facebooker/model.rb +6 -4
  12. data/lib/facebooker/models/user.rb +39 -4
  13. data/lib/facebooker/parser.rb +14 -0
  14. data/lib/facebooker/rails/controller.rb +34 -10
  15. data/lib/facebooker/rails/extensions/action_controller.rb +48 -0
  16. data/lib/facebooker/rails/extensions/rack_setup.rb +2 -0
  17. data/lib/facebooker/rails/extensions/routing.rb +15 -0
  18. data/lib/facebooker/rails/facebook_url_helper.rb +3 -3
  19. data/lib/facebooker/rails/facebook_url_rewriting.rb +18 -5
  20. data/lib/facebooker/rails/helpers.rb +19 -2
  21. data/lib/facebooker/rails/helpers/fb_connect.rb +20 -10
  22. data/lib/facebooker/rails/publisher.rb +9 -5
  23. data/lib/facebooker/service.rb +1 -2
  24. data/lib/facebooker/session.rb +13 -1
  25. data/lib/facebooker/version.rb +1 -1
  26. data/lib/rack/facebook.rb +77 -0
  27. data/lib/tasks/tunnel.rake +3 -3
  28. data/test/facebooker/logging_test.rb +2 -2
  29. data/test/facebooker/models/user_test.rb +39 -3
  30. data/test/facebooker/rails/publisher_test.rb +19 -3
  31. data/test/facebooker/rails_integration_test.rb +52 -6
  32. data/test/rack/facebook_test.rb +62 -0
  33. data/test/rails_test_helper.rb +2 -0
  34. metadata +21 -27
  35. data/CHANGELOG.txt +0 -0
  36. data/Manifest.txt +0 -127
  37. data/README +0 -46
  38. data/lib/facebooker/models/user.rb.orig +0 -396
  39. data/lib/facebooker/models/user.rb.rej +0 -17
  40. data/lib/facebooker/session.rb.orig +0 -564
  41. data/lib/facebooker/session.rb.rej +0 -29
@@ -1,17 +0,0 @@
1
- ***************
2
- *** 10,16 ****
3
- include Model
4
- attr_accessor :message, :time, :status_id
5
- end
6
- - FIELDS = [: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, :uid, :work_history, :sex, :religion, :notes_count, :activities, :pic_square, :movies, :has_added_app, :education_history, :birthday, :first_name, :meeting_for, :last_name, :interests, :current_location, :pic, :books, :affiliations, :locale, :profile_url, :proxied_email]
7
- STANDARD_FIELDS = [:uid, :first_name, :last_name, :name, :timezone, :birthday, :sex, :affiliations, :locale, :profile_url]
8
- attr_accessor :id, :session
9
- populating_attr_accessor *FIELDS
10
- --- 10,16 ----
11
- include Model
12
- attr_accessor :message, :time, :status_id
13
- end
14
- + FIELDS = [: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, :uid, :work_history, :sex, :religion, :notes_count, :activities, :pic_square, :movies, :has_added_app, :education_history, :birthday, :first_name, :meeting_for, :last_name, :interests, :current_location, :pic, :books, :affiliations, :locale, :profile_url, :proxied_email, :email_hashes]
15
- STANDARD_FIELDS = [:uid, :first_name, :last_name, :name, :timezone, :birthday, :sex, :affiliations, :locale, :profile_url]
16
- attr_accessor :id, :session
17
- populating_attr_accessor *FIELDS
@@ -1,564 +0,0 @@
1
- require 'cgi'
2
-
3
- module Facebooker
4
- #
5
- # Raised when trying to perform an operation on a user
6
- # other than the logged in user (if that's unallowed)
7
- class NonSessionUser < StandardError; end
8
- class Session
9
- class SessionExpired < StandardError; end
10
- class UnknownError < StandardError; end
11
- class ServiceUnavailable < StandardError; end
12
- class MaxRequestsDepleted < StandardError; end
13
- class HostNotAllowed < StandardError; end
14
- class MissingOrInvalidParameter < StandardError; end
15
- class InvalidAPIKey < StandardError; end
16
- class SessionExpired < StandardError; end
17
- class CallOutOfOrder < StandardError; end
18
- class IncorrectSignature < StandardError; end
19
- class SignatureTooOld < StandardError; end
20
- class TooManyUserCalls < StandardError; end
21
- class TooManyUserActionCalls < StandardError; end
22
- class InvalidFeedTitleLink < StandardError; end
23
- class InvalidFeedTitleLength < StandardError; end
24
- class InvalidFeedTitleName < StandardError; end
25
- class BlankFeedTitle < StandardError; end
26
- class FeedBodyLengthTooLong < StandardError; end
27
- class InvalidFeedPhotoSource < StandardError; end
28
- class InvalidFeedPhotoLink < StandardError; end
29
- class TemplateDataMissingRequiredTokens < StandardError; end
30
- class FeedMarkupInvalid < StandardError; end
31
- class FeedTitleDataInvalid < StandardError; end
32
- class FeedTitleTemplateInvalid < StandardError; end
33
- class FeedBodyDataInvalid < StandardError; end
34
- class FeedBodyTemplateInvalid < StandardError; end
35
- class FeedPhotosNotRetrieved < StandardError; end
36
- class FeedTargetIdsInvalid < StandardError; end
37
- class TemplateBundleInvalid < StandardError; end
38
- class ConfigurationMissing < StandardError; end
39
- class FQLParseError < StandardError; end
40
- class FQLFieldDoesNotExist < StandardError; end
41
- class FQLTableDoesNotExist < StandardError; end
42
- class FQLStatementNotIndexable < StandardError; end
43
- class FQLFunctionDoesNotExist < StandardError; end
44
- class FQLWrongNumberArgumentsPassedToFunction < StandardError; end
45
- class InvalidAlbumId < StandardError; end
46
- class AlbumIsFull < StandardError; end
47
- class MissingOrInvalidImageFile < StandardError; end
48
- class TooManyUnapprovedPhotosPending < StandardError; end
49
- class ExtendedPermissionRequired < StandardError; end
50
- class InvalidFriendList < StandardError; end
51
- class UserRegistrationFailed < StandardError
52
- attr_accessor :failed_users
53
- end
54
-
55
- API_SERVER_BASE_URL = ENV["FACEBOOKER_API"] == "new" ? "api.new.facebook.com" : "api.facebook.com"
56
- API_PATH_REST = "/restserver.php"
57
- WWW_SERVER_BASE_URL = ENV["FACEBOOKER_API"] == "new" ? "www.new.facebook.com" : "www.facebook.com"
58
- WWW_PATH_LOGIN = "/login.php"
59
- WWW_PATH_ADD = "/add.php"
60
- WWW_PATH_INSTALL = "/install.php"
61
-
62
- attr_writer :auth_token
63
- attr_reader :session_key
64
-
65
- def self.create(api_key=nil, secret_key=nil)
66
- api_key ||= self.api_key
67
- secret_key ||= self.secret_key
68
- raise ArgumentError unless !api_key.nil? && !secret_key.nil?
69
- new(api_key, secret_key)
70
- end
71
-
72
- def self.api_key
73
- extract_key_from_environment(:api) || extract_key_from_configuration_file(:api) rescue report_inability_to_find_key(:api)
74
- end
75
-
76
- def self.secret_key
77
- extract_key_from_environment(:secret) || extract_key_from_configuration_file(:secret) rescue report_inability_to_find_key(:secret)
78
- end
79
-
80
- def self.current
81
- @current_session
82
- end
83
-
84
- def self.current=(session)
85
- @current_session=session
86
- end
87
-
88
- def login_url(options={})
89
- options = default_login_url_options.merge(options)
90
- "#{Facebooker.login_url_base(@api_key)}#{login_url_optional_parameters(options)}"
91
- end
92
-
93
- def install_url(options={})
94
- "#{Facebooker.install_url_base(@api_key)}#{install_url_optional_parameters(options)}"
95
- end
96
-
97
- def permission_url(permission,options={})
98
- options = default_login_url_options.merge(options)
99
- "http://#{Facebooker.www_server_base_url}/authorize.php?api_key=#{@api_key}&v=1.0&ext_perm=#{permission}#{install_url_optional_parameters(options)}"
100
- end
101
-
102
- def install_url_optional_parameters(options)
103
- optional_parameters = []
104
- optional_parameters += add_next_parameters(options)
105
- optional_parameters.join
106
- end
107
-
108
- def add_next_parameters(options)
109
- opts = []
110
- opts << "&next=#{CGI.escape(options[:next])}" if options[:next]
111
- opts << "&next_cancel=#{CGI.escape(options[:next_cancel])}" if options[:next_cancel]
112
- opts
113
- end
114
-
115
- def login_url_optional_parameters(options)
116
- # It is important that unused options are omitted as stuff like &canvas=false will still display the canvas.
117
- optional_parameters = []
118
- optional_parameters += add_next_parameters(options)
119
- optional_parameters << "&skipcookie=true" if options[:skip_cookie]
120
- optional_parameters << "&hide_checkbox=true" if options[:hide_checkbox]
121
- optional_parameters << "&canvas=true" if options[:canvas]
122
- optional_parameters.join
123
- end
124
-
125
- def default_login_url_options
126
- {}
127
- end
128
-
129
- def initialize(api_key, secret_key)
130
- @api_key = api_key
131
- @secret_key = secret_key
132
- end
133
-
134
- def secret_for_method(method_name)
135
- @secret_key
136
- end
137
-
138
- def auth_token
139
- @auth_token ||= post 'facebook.auth.createToken'
140
- end
141
-
142
- def infinite?
143
- @expires == 0
144
- end
145
-
146
- def expired?
147
- @expires.nil? || (!infinite? && Time.at(@expires) <= Time.now)
148
- end
149
-
150
- def secured?
151
- !@session_key.nil? && !expired?
152
- end
153
-
154
- def secure!
155
- response = post 'facebook.auth.getSession', :auth_token => auth_token
156
- secure_with!(response['session_key'], response['uid'], response['expires'], response['secret'])
157
- end
158
-
159
- def secure_with!(session_key, uid = nil, expires = nil, secret_from_session = nil)
160
- @session_key = session_key
161
- @uid = uid ? Integer(uid) : post('facebook.users.getLoggedInUser', :session_key => session_key)
162
- @expires = Integer(expires)
163
- @secret_from_session = secret_from_session
164
- end
165
-
166
- def fql_query(query, format = 'XML')
167
- post('facebook.fql.query', :query => query, :format => format) do |response|
168
- type = response.shift
169
- return [] if type.nil?
170
- response.shift.map do |hash|
171
- case type
172
- when 'user'
173
- user = User.new
174
- user.session = self
175
- user.populate_from_hash!(hash)
176
- user
177
- when 'photo'
178
- Photo.from_hash(hash)
179
- when 'event_member'
180
- Event::Attendance.from_hash(hash)
181
- end
182
- end
183
- end
184
- end
185
-
186
- def user
187
- @user ||= User.new(uid, self)
188
- end
189
-
190
- #
191
- # This one has so many parameters, a Hash seemed cleaner than a long param list. Options can be:
192
- # :uid => Filter by events associated with a user with this uid
193
- # :eids => Filter by this list of event ids. This is a comma-separated list of eids.
194
- # :start_time => Filter with this UTC as lower bound. A missing or zero parameter indicates no lower bound. (Time or Integer)
195
- # :end_time => Filter with this UTC as upper bound. A missing or zero parameter indicates no upper bound. (Time or Integer)
196
- # :rsvp_status => Filter by this RSVP status.
197
- def events(options = {})
198
- @events ||= post('facebook.events.get', options) do |response|
199
- response.map do |hash|
200
- Event.from_hash(hash)
201
- end
202
- end
203
- end
204
-
205
- def event_members(eid)
206
- @members ||= post('facebook.events.getMembers', :eid => eid) do |response|
207
- response.map do |attendee_hash|
208
- Event::Attendance.from_hash(attendee_hash)
209
- end
210
- end
211
- end
212
-
213
- def users_standard(user_ids, fields=[])
214
- post("facebook.users.getStandardInfo",:uids=>user_ids.join(","),:fields=>User.user_fields(fields)) do |users|
215
- users.map { |u| User.new(u)}
216
- end
217
- end
218
-
219
- def users(user_ids, fields=[])
220
- post("facebook.users.getInfo",:uids=>user_ids.join(","),:fields=>User.standard_fields(fields)) do |users|
221
- users.map { |u| User.new(u)}
222
- end
223
- end
224
-
225
- def pages(options = {})
226
- raise ArgumentError, 'fields option is mandatory' unless options.has_key?(:fields)
227
- @pages ||= {}
228
- @pages[options] ||= post('facebook.pages.getInfo', options) do |response|
229
- response.map do |hash|
230
- Page.from_hash(hash)
231
- end
232
- end
233
- end
234
-
235
- #
236
- # Returns a proxy object for handling calls to Facebook cached items
237
- # such as images and FBML ref handles
238
- def server_cache
239
- Facebooker::ServerCache.new(self)
240
- end
241
-
242
- #
243
- # Returns a proxy object for handling calls to the Facebook Data API
244
- def data
245
- Facebooker::Data.new(self)
246
- end
247
-
248
- def admin
249
- Facebooker::Admin.new(self)
250
- end
251
-
252
- #
253
- # Given an array like:
254
- # [[userid, otheruserid], [yetanotherid, andanotherid]]
255
- # returns a Hash indicating friendship of those pairs:
256
- # {[userid, otheruserid] => true, [yetanotherid, andanotherid] => false}
257
- # if one of the Hash values is nil, it means the facebook platform's answer is "I don't know"
258
- def check_friendship(array_of_pairs_of_users)
259
- uids1 = []
260
- uids2 = []
261
- array_of_pairs_of_users.each do |pair|
262
- uids1 << pair.first
263
- uids2 << pair.last
264
- end
265
- post('facebook.friends.areFriends', :uids1 => uids1.join(','), :uids2 => uids2.join(','))
266
- end
267
-
268
- def get_photos(pids = nil, subj_id = nil, aid = nil)
269
- if [subj_id, pids, aid].all? {|arg| arg.nil?}
270
- raise ArgumentError, "Can't get a photo without a picture, album or subject ID"
271
- end
272
- @photos = post('facebook.photos.get', :subj_id => subj_id, :pids => pids, :aid => aid ) do |response|
273
- response.map do |hash|
274
- Photo.from_hash(hash)
275
- end
276
- end
277
- end
278
-
279
- def get_albums(aids)
280
- @albums = post('facebook.photos.getAlbums', :aids => aids) do |response|
281
- response.map do |hash|
282
- Album.from_hash(hash)
283
- end
284
- end
285
- end
286
-
287
- def get_tags(pids)
288
- @tags = post('facebook.photos.getTags', :pids => pids) do |response|
289
- response.map do |hash|
290
- Tag.from_hash(hash)
291
- end
292
- end
293
- end
294
-
295
- def add_tags(pid, x, y, tag_uid = nil, tag_text = nil )
296
- if [tag_uid, tag_text].all? {|arg| arg.nil?}
297
- raise ArgumentError, "Must enter a name or string for this tag"
298
- end
299
- @tags = post('facebook.photos.addTag', :pid => pid, :tag_uid => tag_uid, :tag_text => tag_text, :x => x, :y => y )
300
- end
301
-
302
- def send_notification(user_ids, fbml, email_fbml = nil)
303
- params = {:notification => fbml, :to_ids => user_ids.map{ |id| User.cast_to_facebook_id(id)}.join(',')}
304
- if email_fbml
305
- params[:email] = email_fbml
306
- end
307
- params[:type]="user_to_user"
308
- # if there is no uid, this is an announcement
309
- unless uid?
310
- params[:type]="app_to_user"
311
- end
312
-
313
- post 'facebook.notifications.send', params,uid?
314
- end
315
-
316
- ##
317
- # Register a template bundle with Facebook.
318
- # returns the template id to use to send using this template
319
- def register_template_bundle(one_line_story_templates,short_story_templates=nil,full_story_template=nil, action_links=nil)
320
- if !one_line_story_templates.is_a?(Array)
321
- one_line_story_templates = [one_line_story_templates]
322
- end
323
- parameters = {:one_line_story_templates=>one_line_story_templates.to_json}
324
-
325
- if !action_links.blank?
326
- parameters[:action_links] = action_links.to_json
327
- end
328
-
329
- if !short_story_templates.blank?
330
- short_story_templates = [short_story_templates] unless short_story_templates.is_a?(Array)
331
- parameters[:short_story_templates]= short_story_templates.to_json
332
- end
333
-
334
- if !full_story_template.blank?
335
- parameters[:full_story_template]= full_story_template.to_json
336
- end
337
- post("facebook.feed.registerTemplateBundle", parameters,false)
338
- end
339
-
340
- ##
341
- # publish a previously rendered template bundle
342
- # see http://wiki.developers.facebook.com/index.php/Feed.publishUserAction
343
- #
344
- def publish_user_action(bundle_id,data={},target_ids=nil,body_general=nil)
345
- parameters={:template_bundle_id=>bundle_id,:template_data=>data.to_json}
346
- parameters[:target_ids] = target_ids unless target_ids.blank?
347
- parameters[:body_general] = body_general unless body_general.blank?
348
- post("facebook.feed.publishUserAction", parameters)
349
- end
350
-
351
-
352
- ##
353
- # Send email to as many as 100 users at a time
354
- def send_email(user_ids, subject, text, fbml = nil)
355
- user_ids = Array(user_ids)
356
- params = {:fbml => fbml, :recipients => user_ids.map{ |id| User.cast_to_facebook_id(id)}.join(','), :text => text, :subject => subject}
357
- post 'facebook.notifications.sendEmail', params
358
- end
359
-
360
- # Only serialize the bare minimum to recreate the session.
361
- def marshal_load(variables)#:nodoc:
362
- fields_to_serialize.each_with_index{|field, index| instance_variable_set_value(field, variables[index])}
363
- end
364
-
365
- # Only serialize the bare minimum to recreate the session.
366
- def marshal_dump#:nodoc:
367
- fields_to_serialize.map{|field| instance_variable_value(field)}
368
- end
369
-
370
- # Only serialize the bare minimum to recreate the session.
371
- def to_yaml( opts = {} )
372
- YAML::quick_emit(self.object_id, opts) do |out|
373
- out.map(taguri) do |map|
374
- fields_to_serialize.each do |field|
375
- map.add(field, instance_variable_value(field))
376
- end
377
- end
378
- end
379
- end
380
-
381
- def instance_variable_set_value(field, value)
382
- self.instance_variable_set("@#{field}", value)
383
- end
384
-
385
- def instance_variable_value(field)
386
- self.instance_variable_get("@#{field}")
387
- end
388
-
389
- def fields_to_serialize
390
- %w(session_key uid expires secret_from_session auth_token api_key secret_key)
391
- end
392
-
393
- class Desktop < Session
394
- def login_url
395
- super + "&auth_token=#{auth_token}"
396
- end
397
-
398
- def secret_for_method(method_name)
399
- secret = auth_request_methods.include?(method_name) ? super : @secret_from_session
400
- secret
401
- end
402
-
403
- def post(method, params = {},use_session=false)
404
- if method == 'facebook.profile.getFBML' || method == 'facebook.profile.setFBML'
405
- raise NonSessionUser.new("User #{@uid} is not the logged in user.") unless @uid == params[:uid]
406
- end
407
- super
408
- end
409
- private
410
- def auth_request_methods
411
- ['facebook.auth.getSession', 'facebook.auth.createToken']
412
- end
413
- end
414
-
415
- def batch_request?
416
- @batch_request
417
- end
418
-
419
- def add_to_batch(req,&proc)
420
- batch_request = BatchRequest.new(req,proc)
421
- Thread.current[:facebooker_current_batch_queue]<<batch_request
422
- batch_request
423
- end
424
-
425
- # Submit the enclosed requests for this session inside a batch
426
- #
427
- # All requests will be sent to Facebook at the end of the block
428
- # each method inside the block will return a proxy object
429
- # attempting to access the proxy before the end of the block will yield an exception
430
- #
431
- # For Example:
432
- #
433
- # facebook_session.batch do
434
- # @send_result = facebook_session.send_notification([12451752],"Woohoo")
435
- # @albums = facebook_session.user.albums
436
- # end
437
- # puts @albums.first.inspect
438
- #
439
- # is valid, however
440
- #
441
- # facebook_session.batch do
442
- # @send_result = facebook_session.send_notification([12451752],"Woohoo")
443
- # @albums = facebook_session.user.albums
444
- # puts @albums.first.inspect
445
- # end
446
- #
447
- # will raise Facebooker::BatchRequest::UnexecutedRequest
448
- #
449
- # If an exception is raised while processing the result, that exception will be
450
- # re-raised on the next access to that object or when exception_raised? is called
451
- #
452
- # for example, if the send_notification resulted in TooManyUserCalls being raised,
453
- # calling
454
- # @send_result.exception_raised?
455
- # would re-raise that exception
456
- # if there was an error retrieving the albums, it would be re-raised when
457
- # @albums.first
458
- # is called
459
- #
460
- def batch(serial_only=false)
461
- @batch_request=true
462
- Thread.current[:facebooker_current_batch_queue]=[]
463
- yield
464
- # Set the batch request to false so that post will execute the batch job
465
- @batch_request=false
466
- BatchRun.current_batch=Thread.current[:facebooker_current_batch_queue]
467
- post("facebook.batch.run",:method_feed=>BatchRun.current_batch.map{|q| q.uri}.to_json,:serial_only=>serial_only.to_s)
468
- ensure
469
- @batch_request=false
470
- BatchRun.current_batch=nil
471
- end
472
-
473
- def post_without_logging(method, params = {}, use_session_key = true, &proc)
474
- add_facebook_params(params, method)
475
- use_session_key && @session_key && params[:session_key] ||= @session_key
476
- final_params=params.merge(:sig => signature_for(params))
477
- if batch_request?
478
- add_to_batch(final_params,&proc)
479
- else
480
- result = service.post(final_params)
481
- result = yield result if block_given?
482
- result
483
- end
484
- end
485
-
486
- def post(method, params = {}, use_session_key = true, &proc)
487
- if batch_request?
488
- post_without_logging(method, params, use_session_key, &proc)
489
- else
490
- Logging.log_fb_api(method, params) do
491
- post_without_logging(method, params, use_session_key, &proc)
492
- end
493
- end
494
- end
495
-
496
- def post_file(method, params = {})
497
- Logging.log_fb_api(method, params) do
498
- add_facebook_params(params, method)
499
- @session_key && params[:session_key] ||= @session_key
500
- service.post_file(params.merge(:sig => signature_for(params.reject{|key, value| key.nil?})))
501
- end
502
- end
503
-
504
-
505
- def self.configuration_file_path
506
- @configuration_file_path || File.expand_path("~/.facebookerrc")
507
- end
508
-
509
- def self.configuration_file_path=(path)
510
- @configuration_file_path = path
511
- end
512
-
513
- private
514
- def add_facebook_params(hash, method)
515
- hash[:method] = method
516
- hash[:api_key] = @api_key
517
- hash[:call_id] = Time.now.to_f.to_s unless method == 'facebook.auth.getSession'
518
- hash[:v] = "1.0"
519
- end
520
-
521
- # This ultimately delgates to the adapter
522
- def self.extract_key_from_environment(key_name)
523
- Facebooker.send(key_name.to_s + "_key") rescue nil
524
- end
525
-
526
- def self.extract_key_from_configuration_file(key_name)
527
- read_configuration_file[key_name]
528
- end
529
-
530
- def self.report_inability_to_find_key(key_name)
531
- raise ConfigurationMissing, "Could not find configuration information for #{key_name}"
532
- end
533
-
534
- def self.read_configuration_file
535
- eval(File.read(configuration_file_path))
536
- end
537
-
538
- def service
539
- @service ||= Service.new(Facebooker.api_server_base, Facebooker.api_rest_path, @api_key)
540
- end
541
-
542
- def uid
543
- @uid || (secure!; @uid)
544
- end
545
-
546
- def uid?
547
- ! @uid.nil?
548
- end
549
-
550
- def signature_for(params)
551
- raw_string = params.inject([]) do |collection, pair|
552
- collection << pair.join("=")
553
- collection
554
- end.sort.join
555
- Digest::MD5.hexdigest([raw_string, secret_for_method(params[:method])].join)
556
- end
557
- end
558
-
559
- class CanvasSession < Session
560
- def default_login_url_options
561
- {:canvas => true}
562
- end
563
- end
564
- end