tenderlove-facebooker 1.0.16.20090319151701

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.
Files changed (124) hide show
  1. data/CHANGELOG.rdoc +17 -0
  2. data/COPYING.rdoc +19 -0
  3. data/Manifest.txt +123 -0
  4. data/README.rdoc +103 -0
  5. data/Rakefile +86 -0
  6. data/TODO.rdoc +4 -0
  7. data/examples/desktop_login.rb +14 -0
  8. data/facebooker.gemspec +38 -0
  9. data/generators/facebook/facebook_generator.rb +14 -0
  10. data/generators/facebook/templates/config/facebooker.yml +46 -0
  11. data/generators/facebook/templates/public/javascripts/facebooker.js +99 -0
  12. data/generators/facebook_controller/USAGE +33 -0
  13. data/generators/facebook_controller/facebook_controller_generator.rb +40 -0
  14. data/generators/facebook_controller/templates/controller.rb +7 -0
  15. data/generators/facebook_controller/templates/functional_test.rb +11 -0
  16. data/generators/facebook_controller/templates/helper.rb +2 -0
  17. data/generators/facebook_controller/templates/view.fbml.erb +2 -0
  18. data/generators/facebook_controller/templates/view.html.erb +2 -0
  19. data/generators/facebook_publisher/facebook_publisher_generator.rb +14 -0
  20. data/generators/facebook_publisher/templates/create_facebook_templates.rb +15 -0
  21. data/generators/facebook_publisher/templates/publisher.rb +3 -0
  22. data/generators/facebook_scaffold/USAGE +27 -0
  23. data/generators/facebook_scaffold/facebook_scaffold_generator.rb +118 -0
  24. data/generators/facebook_scaffold/templates/controller.rb +93 -0
  25. data/generators/facebook_scaffold/templates/facebook_style.css +2579 -0
  26. data/generators/facebook_scaffold/templates/functional_test.rb +89 -0
  27. data/generators/facebook_scaffold/templates/helper.rb +2 -0
  28. data/generators/facebook_scaffold/templates/layout.fbml.erb +6 -0
  29. data/generators/facebook_scaffold/templates/layout.html.erb +17 -0
  30. data/generators/facebook_scaffold/templates/style.css +74 -0
  31. data/generators/facebook_scaffold/templates/view_edit.fbml.erb +13 -0
  32. data/generators/facebook_scaffold/templates/view_edit.html.erb +18 -0
  33. data/generators/facebook_scaffold/templates/view_index.fbml.erb +24 -0
  34. data/generators/facebook_scaffold/templates/view_index.html.erb +24 -0
  35. data/generators/facebook_scaffold/templates/view_new.fbml.erb +12 -0
  36. data/generators/facebook_scaffold/templates/view_new.html.erb +17 -0
  37. data/generators/facebook_scaffold/templates/view_show.fbml.erb +10 -0
  38. data/generators/facebook_scaffold/templates/view_show.html.erb +10 -0
  39. data/generators/publisher/publisher_generator.rb +14 -0
  40. data/generators/xd_receiver/templates/xd_receiver.html +10 -0
  41. data/generators/xd_receiver/xd_receiver_generator.rb +9 -0
  42. data/init.rb +72 -0
  43. data/install.rb +12 -0
  44. data/lib/facebooker/adapters/adapter_base.rb +87 -0
  45. data/lib/facebooker/adapters/bebo_adapter.rb +75 -0
  46. data/lib/facebooker/adapters/facebook_adapter.rb +52 -0
  47. data/lib/facebooker/admin.rb +42 -0
  48. data/lib/facebooker/batch_request.rb +44 -0
  49. data/lib/facebooker/data.rb +57 -0
  50. data/lib/facebooker/feed.rb +78 -0
  51. data/lib/facebooker/logging.rb +51 -0
  52. data/lib/facebooker/mobile.rb +20 -0
  53. data/lib/facebooker/mock/service.rb +50 -0
  54. data/lib/facebooker/mock/session.rb +18 -0
  55. data/lib/facebooker/model.rb +135 -0
  56. data/lib/facebooker/models/affiliation.rb +10 -0
  57. data/lib/facebooker/models/album.rb +11 -0
  58. data/lib/facebooker/models/applicationproperties.rb +39 -0
  59. data/lib/facebooker/models/applicationrestrictions.rb +10 -0
  60. data/lib/facebooker/models/cookie.rb +10 -0
  61. data/lib/facebooker/models/education_info.rb +11 -0
  62. data/lib/facebooker/models/event.rb +28 -0
  63. data/lib/facebooker/models/friend_list.rb +16 -0
  64. data/lib/facebooker/models/group.rb +36 -0
  65. data/lib/facebooker/models/info_item.rb +10 -0
  66. data/lib/facebooker/models/info_section.rb +10 -0
  67. data/lib/facebooker/models/location.rb +8 -0
  68. data/lib/facebooker/models/notifications.rb +17 -0
  69. data/lib/facebooker/models/page.rb +27 -0
  70. data/lib/facebooker/models/photo.rb +12 -0
  71. data/lib/facebooker/models/tag.rb +12 -0
  72. data/lib/facebooker/models/user.rb +426 -0
  73. data/lib/facebooker/models/video.rb +9 -0
  74. data/lib/facebooker/models/work_info.rb +9 -0
  75. data/lib/facebooker/parser.rb +589 -0
  76. data/lib/facebooker/rails/controller.rb +304 -0
  77. data/lib/facebooker/rails/cucumber/world.rb +46 -0
  78. data/lib/facebooker/rails/cucumber.rb +28 -0
  79. data/lib/facebooker/rails/facebook_form_builder.rb +112 -0
  80. data/lib/facebooker/rails/facebook_pretty_errors.rb +22 -0
  81. data/lib/facebooker/rails/facebook_request_fix.rb +24 -0
  82. data/lib/facebooker/rails/facebook_session_handling.rb +69 -0
  83. data/lib/facebooker/rails/facebook_url_helper.rb +192 -0
  84. data/lib/facebooker/rails/facebook_url_rewriting.rb +39 -0
  85. data/lib/facebooker/rails/helpers/fb_connect.rb +89 -0
  86. data/lib/facebooker/rails/helpers.rb +762 -0
  87. data/lib/facebooker/rails/integration_session.rb +38 -0
  88. data/lib/facebooker/rails/profile_publisher_extensions.rb +42 -0
  89. data/lib/facebooker/rails/publisher.rb +526 -0
  90. data/lib/facebooker/rails/routing.rb +49 -0
  91. data/lib/facebooker/rails/test_helpers.rb +68 -0
  92. data/lib/facebooker/rails/utilities.rb +22 -0
  93. data/lib/facebooker/server_cache.rb +24 -0
  94. data/lib/facebooker/service.rb +94 -0
  95. data/lib/facebooker/session.rb +584 -0
  96. data/lib/facebooker/version.rb +9 -0
  97. data/lib/facebooker.rb +174 -0
  98. data/lib/net/http_multipart_post.rb +123 -0
  99. data/lib/tasks/facebooker.rake +18 -0
  100. data/lib/tasks/tunnel.rake +46 -0
  101. data/rails/init.rb +1 -0
  102. data/setup.rb +1585 -0
  103. data/templates/layout.erb +24 -0
  104. data/test/facebooker/adapters_test.rb +96 -0
  105. data/test/facebooker/admin_test.rb +102 -0
  106. data/test/facebooker/batch_request_test.rb +83 -0
  107. data/test/facebooker/data_test.rb +86 -0
  108. data/test/facebooker/logging_test.rb +43 -0
  109. data/test/facebooker/mobile_test.rb +45 -0
  110. data/test/facebooker/model_test.rb +123 -0
  111. data/test/facebooker/models/event_test.rb +15 -0
  112. data/test/facebooker/models/user_test.rb +295 -0
  113. data/test/facebooker/rails/publisher_test.rb +452 -0
  114. data/test/facebooker/rails_integration_test.rb +1312 -0
  115. data/test/facebooker/server_cache_test.rb +44 -0
  116. data/test/facebooker/session_test.rb +614 -0
  117. data/test/facebooker_test.rb +925 -0
  118. data/test/fixtures/multipart_post_body_with_only_parameters.txt +33 -0
  119. data/test/fixtures/multipart_post_body_with_single_file.txt +38 -0
  120. data/test/fixtures/multipart_post_body_with_single_file_that_has_nil_key.txt +38 -0
  121. data/test/net/http_multipart_post_test.rb +52 -0
  122. data/test/rails_test_helper.rb +11 -0
  123. data/test/test_helper.rb +66 -0
  124. metadata +217 -0
@@ -0,0 +1,192 @@
1
+ # Extends the ActionView::Helpers::UrlHelper module. See it for details on
2
+ # the usual url helper methods: url_for, link_to, button_to, etc.
3
+ #
4
+ # Mostly, the changes sanitize javascript into facebook javascript.
5
+ # It sanitizes link_to solely by altering the private methods:
6
+ # convert_options_to_javascript!, confirm_javascript_function, and
7
+ # method_javascript_function. For button_to, it alters button_to
8
+ # itself, as well as confirm_javascript_function. No other methods
9
+ # need to be changed because of Facebook javascript.
10
+ #
11
+ # For button_to and link_to, adds alternate confirm options for facebook.
12
+ # ==== Options
13
+ # * <tt>:confirm => 'question?'</tt> - This will add a JavaScript confirm
14
+ # prompt with the question specified.
15
+ #
16
+ # Example:
17
+ # # Generates: <a href="http://rubyforge.org/projects/facebooker" onclick="
18
+ # # var dlg = new Dialog().showChoice('Please Confirm', 'Go to Facebooker?').setStyle();
19
+ # # var a=this;dlg.onconfirm = function() {
20
+ # # document.setLocation(a.getHref());
21
+ # # }; return false;">Facebooker</a>
22
+ # link_to("Facebooker", "http://rubyforge.org/projects/facebooker", :confirm=>"Go to Facebooker?")
23
+ #
24
+ # Alternatively, options[:confirm] may be specified.
25
+ # See the Facebook page http://wiki.developers.facebook.com/index.php/FBJS.
26
+ # These options are:
27
+ # <tt>:title</tt>:: Specifies the title of the Facebook dialog. Default is "Please Confirm".
28
+ # <tt>:content</tt>:: Specifies the title of the Facebook dialog. Default is "Are you sure?".
29
+ #
30
+ # Example:
31
+ # # Generates: <a href="http://rubyforge.org/projects/facebooker" onclick="
32
+ # # var dlg = new Dialog().showChoice('the page says:', 'Go to Facebooker?').setStyle();
33
+ # # var a=this;dlg.onconfirm = function() {
34
+ # # document.setLocation(a.getHref());
35
+ # # }; return false;">Facebooker</a>
36
+ # link_to("Facebooker", "http://rubyforge.org/projects/facebooker", :confirm=>{:title=>"the page says:", :content=>"Go to Facebooker?"})
37
+ #
38
+ # Any other options passed are assumed to be css styles.
39
+ # Again, see the Facebook page http://wiki.developers.facebook.com/index.php/FBJS.
40
+ #
41
+ # Example:
42
+ # # Generates: <a href="http://rubyforge.org/projects/facebooker" onclick="
43
+ # # var dlg = new Dialog().showChoice('the page says:', 'Are you sure?').setStyle({color: 'pink', width: '200px'});
44
+ # # var a=this;dlg.onconfirm = function() {
45
+ # # document.setLocation(a.getHref());
46
+ # # }; return false;">Facebooker</a>
47
+ # link_to("Facebooker", "http://rubyforge.org/projects/facebooker", :confirm=>{:title=>"the page says:, :color=>"pink", :width=>"200px"})
48
+ module ActionView
49
+ module Helpers
50
+ module UrlHelper
51
+ # Alters one and only one line of the Rails button_to. See below.
52
+ def button_to_with_facebooker(name, options={}, html_options = {})
53
+ if !request_comes_from_facebook?
54
+ button_to_without_facebooker(name,options,html_options)
55
+ else
56
+ html_options = html_options.stringify_keys
57
+ convert_boolean_attributes!(html_options, %w( disabled ))
58
+
59
+ method_tag = ''
60
+ if (method = html_options.delete('method')) && %w{put delete}.include?(method.to_s)
61
+ method_tag = tag('input', :type => 'hidden', :name => '_method', :value => method.to_s)
62
+ end
63
+
64
+ form_method = method.to_s == 'get' ? 'get' : 'post'
65
+
66
+ request_token_tag = ''
67
+ if form_method == 'post' && protect_against_forgery?
68
+ request_token_tag = tag(:input, :type => "hidden", :name => request_forgery_protection_token.to_s, :value => form_authenticity_token)
69
+ end
70
+
71
+ if confirm = html_options.delete("confirm")
72
+ # this line is the only change => html_options["onclick"] = "return #{confirm_javascript_function(confirm)}"
73
+ html_options["onclick"] = "#{confirm_javascript_function(confirm, 'a.getForm().submit();')}return false;"
74
+ end
75
+
76
+ url = options.is_a?(String) ? options : self.url_for(options)
77
+ name ||= url
78
+
79
+ html_options.merge!("type" => "submit", "value" => name)
80
+
81
+ "<form method=\"#{form_method}\" action=\"#{escape_once url}\" class=\"button-to\"><div>" +
82
+ method_tag + tag("input", html_options) + request_token_tag + "</div></form>"
83
+ end
84
+ end
85
+
86
+ alias_method_chain :button_to, :facebooker
87
+
88
+ private
89
+
90
+ # Altered to throw an error on :popup and sanitize the javascript
91
+ # for Facebook.
92
+ def convert_options_to_javascript_with_facebooker!(html_options, url ='')
93
+ if !respond_to?(:request_comes_from_facebook?) || !request_comes_from_facebook?
94
+ convert_options_to_javascript_without_facebooker!(html_options,url)
95
+ else
96
+ confirm, popup = html_options.delete("confirm"), html_options.delete("popup")
97
+
98
+ method, href = html_options.delete("method"), html_options['href']
99
+
100
+ html_options["onclick"] = case
101
+ when popup
102
+ raise ActionView::ActionViewError, "You can't use :popup"
103
+ when method # or maybe (confirm and method)
104
+ "#{method_javascript_function(method, url, href, confirm)}return false;"
105
+ when confirm # and only confirm
106
+ "#{confirm_javascript_function(confirm)}return false;"
107
+ else
108
+ html_options["onclick"]
109
+ end
110
+ end
111
+ end
112
+
113
+ alias_method_chain :convert_options_to_javascript!, :facebooker
114
+
115
+
116
+ # Overrides a private method that link_to calls via convert_options_to_javascript! and
117
+ # also, button_to calls directly. For Facebook, confirm can be a hash of options to
118
+ # stylize the Facebook dialog. Takes :title, :content, :style options. See
119
+ # the Facebook page http://wiki.developers.facebook.com/index.php/FBJS for valid
120
+ # style formats like "color: 'black', background: 'white'" or like "'color','black'".
121
+ #
122
+ # == Examples ==
123
+ #
124
+ # link_to("Facebooker", "http://rubyforge.org/projects/facebooker", :confirm=>"Go to Facebooker?")
125
+ # link_to("Facebooker", "http://rubyforge.org/projects/facebooker", :confirm=>{:title=>"the page says:, :content=>"Go to Facebooker?"})
126
+ # link_to("Facebooker", "http://rubyforge.org/projects/facebooker", :confirm=>{:title=>"the page says:, :content=>"Go to Facebooker?", :color=>"pink"})
127
+ def confirm_javascript_function_with_facebooker(confirm, fun = nil)
128
+ if !request_comes_from_facebook?
129
+ confirm_javascript_function_without_facebooker(confirm)
130
+ else
131
+ if(confirm.is_a?(Hash))
132
+ confirm_options = confirm.stringify_keys
133
+ title = confirm_options.delete("title") || "Please Confirm"
134
+ content = confirm_options.delete("content") || "Are you sure?"
135
+ button_confirm = confirm_options.delete("button_confirm") || "Okay"
136
+ button_cancel = confirm_options.delete("button_cancel") || "Cancel"
137
+ style = confirm_options.empty? ? "" : convert_options_to_css(confirm_options)
138
+ else
139
+ title,content,style,button_confirm,button_cancel = 'Please Confirm', confirm, "", "Okay", "Cancel"
140
+ end
141
+ "var dlg = new Dialog().showChoice('#{escape_javascript(title.to_s)}','#{escape_javascript(content.to_s)}','#{escape_javascript(button_confirm.to_s)}','#{escape_javascript(button_cancel.to_s)}').setStyle(#{style});"+
142
+ "var a=this;dlg.onconfirm = function() { #{fun ? fun : 'document.setLocation(a.getHref());'} };"
143
+ end
144
+ end
145
+
146
+ alias_method_chain :confirm_javascript_function, :facebooker
147
+
148
+ def convert_options_to_css(options)
149
+ key_pair = options.shift
150
+ style = "{#{key_pair[0]}: '#{key_pair[1]}'"
151
+ for key in options.keys
152
+ style << ", #{key}: '#{options[key]}'"
153
+ end
154
+ style << "}"
155
+ end
156
+
157
+ # Dynamically creates a form for link_to with method. Calls confirm_javascript_function if and
158
+ # only if (confirm && method) for link_to
159
+ def method_javascript_function_with_facebooker(method, url = '', href = nil, confirm = nil)
160
+ if !request_comes_from_facebook?
161
+ method_javascript_function_without_facebooker(method,url,href)
162
+ else
163
+ action = (href && url.size > 0) ? "'#{url}'" : 'a.getHref()'
164
+ submit_function =
165
+ "var f = document.createElement('form'); f.setStyle('display','none'); " +
166
+ "a.getParentNode().appendChild(f); f.setMethod('POST'); f.setAction(#{action});"
167
+
168
+ unless method == :post
169
+ submit_function << "var m = document.createElement('input'); m.setType('hidden'); "
170
+ submit_function << "m.setName('_method'); m.setValue('#{method}'); f.appendChild(m);"
171
+ end
172
+
173
+ if protect_against_forgery?
174
+ submit_function << "var s = document.createElement('input'); s.setType('hidden'); "
175
+ submit_function << "s.setName('#{request_forgery_protection_token}'); s.setValue('#{escape_javascript form_authenticity_token}'); f.appendChild(s);"
176
+ end
177
+ submit_function << "f.submit();"
178
+
179
+ if(confirm)
180
+ confirm_javascript_function(confirm, submit_function)
181
+ else
182
+ "var a=this;" + submit_function
183
+ end
184
+ end
185
+ end
186
+
187
+ alias_method_chain :method_javascript_function, :facebooker
188
+
189
+ end
190
+ end
191
+ end
192
+
@@ -0,0 +1,39 @@
1
+ module ::ActionController
2
+ class AbstractRequest
3
+ def relative_url_root
4
+ Facebooker.path_prefix
5
+ end
6
+ end
7
+
8
+ class Base
9
+ def self.relative_url_root
10
+ Facebooker.path_prefix
11
+ end
12
+ end
13
+
14
+ class UrlRewriter
15
+ RESERVED_OPTIONS << :canvas
16
+ def link_to_new_canvas?
17
+ @request.parameters["fb_sig_in_new_facebook"] == "1"
18
+ end
19
+ def link_to_canvas?(params, options)
20
+ option_override = options[:canvas]
21
+ return false if option_override == false # important to check for false. nil should use default behavior
22
+ option_override || @request.parameters["fb_sig_in_canvas"] == "1" || @request.parameters[:fb_sig_in_canvas] == "1"
23
+ end
24
+
25
+ def rewrite_url_with_facebooker(*args)
26
+ options = args.first.is_a?(Hash) ? args.first : args.last
27
+ is_link_to_canvas = link_to_canvas?(@request.request_parameters, options)
28
+ if is_link_to_canvas && !options.has_key?(:host)
29
+ options[:host] = Facebooker.canvas_server_base
30
+ end
31
+ options.delete(:canvas)
32
+ Facebooker.request_for_canvas(is_link_to_canvas) do
33
+ rewrite_url_without_facebooker(*args)
34
+ end
35
+ end
36
+
37
+ alias_method_chain :rewrite_url, :facebooker
38
+ end
39
+ end
@@ -0,0 +1,89 @@
1
+ module Facebooker
2
+ module Rails
3
+ module Helpers
4
+ module FbConnect
5
+
6
+ def fb_connect_javascript_tag
7
+ if request.ssl?
8
+ javascript_include_tag "https://www.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php"
9
+ else
10
+ javascript_include_tag "http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php"
11
+ end
12
+ end
13
+
14
+ def init_fb_connect(*required_features,&proc)
15
+ additions = ""
16
+ if block_given?
17
+ additions = capture(&proc)
18
+ end
19
+ init_string = "FB.Facebook.init('#{Facebooker.api_key}','/xd_receiver.html');"
20
+ unless required_features.blank?
21
+ init_string = <<-FBML
22
+ Element.observe(window,'load', function() {
23
+ FB_RequireFeatures(#{required_features.to_json}, function() {
24
+ #{init_string}
25
+ #{additions}
26
+ });
27
+ });
28
+ FBML
29
+ end
30
+ if block_given?
31
+ concat javascript_tag(init_string)
32
+ else
33
+ javascript_tag init_string
34
+ end
35
+ end
36
+
37
+ # Render an <fb:login-button> element
38
+ #
39
+ # ==== Examples
40
+ #
41
+ # <%= fb_login_button%>
42
+ # => <fb:login-button></fb:login-button>
43
+ #
44
+ # Specifying a javascript callback
45
+ #
46
+ # <%= fb_login_button 'update_something();'%>
47
+ # => <fb:login-button onlogin='update_something();'></fb:login-button>
48
+ #
49
+ # Adding options <em>See:</em> http://wiki.developers.facebook.com/index.php/Fb:login-button
50
+ #
51
+ # <%= fb_login_button 'update_something();', :size => :small, :background => :dark%>
52
+ # => <fb:login-button background='dark' onlogin='update_something();' size='small'></fb:login-button>
53
+ #
54
+ def fb_login_button(*args)
55
+
56
+ callback = args.first
57
+ options = args.second || {}
58
+ options.merge!(:onlogin=>callback)if callback
59
+
60
+ content_tag("fb:login-button",nil, options)
61
+ end
62
+ def fb_login_and_redirect(url)
63
+ js = update_page do |page|
64
+ page.redirect_to url
65
+ end
66
+ content_tag("fb:login-button",nil,:onlogin=>js)
67
+ end
68
+
69
+ def fb_unconnected_friends_count
70
+ content_tag "fb:unconnected-friends-count",nil
71
+ end
72
+
73
+ def fb_logout_link(text,url)
74
+ js = update_page do |page|
75
+ page.call "FB.Connect.logoutAndRedirect",url
76
+ end
77
+ link_to_function text, js
78
+ end
79
+
80
+ def fb_user_action(action)
81
+ update_page do |page|
82
+ page.call "FB.Connect.showFeedDialog",action.template_id,action.data,action.target_ids,action.body_general,nil,"FB.RequireConnect.promptConnect"
83
+ end
84
+ end
85
+
86
+ end
87
+ end
88
+ end
89
+ end