cwninja-facebooker 1.0.8

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 (115) hide show
  1. data/CHANGELOG.txt +0 -0
  2. data/COPYING +19 -0
  3. data/History.txt +16 -0
  4. data/Manifest.txt +114 -0
  5. data/README +46 -0
  6. data/README.txt +81 -0
  7. data/Rakefile +76 -0
  8. data/TODO.txt +10 -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 +106 -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 +70 -0
  43. data/install.rb +12 -0
  44. data/lib/facebooker.rb +160 -0
  45. data/lib/facebooker/adapters/adapter_base.rb +87 -0
  46. data/lib/facebooker/adapters/bebo_adapter.rb +75 -0
  47. data/lib/facebooker/adapters/facebook_adapter.rb +48 -0
  48. data/lib/facebooker/admin.rb +28 -0
  49. data/lib/facebooker/batch_request.rb +44 -0
  50. data/lib/facebooker/data.rb +57 -0
  51. data/lib/facebooker/feed.rb +78 -0
  52. data/lib/facebooker/logging.rb +51 -0
  53. data/lib/facebooker/model.rb +123 -0
  54. data/lib/facebooker/models/affiliation.rb +10 -0
  55. data/lib/facebooker/models/album.rb +11 -0
  56. data/lib/facebooker/models/applicationproperties.rb +39 -0
  57. data/lib/facebooker/models/cookie.rb +10 -0
  58. data/lib/facebooker/models/education_info.rb +11 -0
  59. data/lib/facebooker/models/event.rb +26 -0
  60. data/lib/facebooker/models/friend_list.rb +14 -0
  61. data/lib/facebooker/models/group.rb +35 -0
  62. data/lib/facebooker/models/info_item.rb +10 -0
  63. data/lib/facebooker/models/info_section.rb +10 -0
  64. data/lib/facebooker/models/location.rb +8 -0
  65. data/lib/facebooker/models/notifications.rb +17 -0
  66. data/lib/facebooker/models/page.rb +27 -0
  67. data/lib/facebooker/models/photo.rb +10 -0
  68. data/lib/facebooker/models/tag.rb +12 -0
  69. data/lib/facebooker/models/user.rb +369 -0
  70. data/lib/facebooker/models/work_info.rb +9 -0
  71. data/lib/facebooker/parser.rb +547 -0
  72. data/lib/facebooker/rails/controller.rb +280 -0
  73. data/lib/facebooker/rails/facebook_asset_path.rb +18 -0
  74. data/lib/facebooker/rails/facebook_form_builder.rb +112 -0
  75. data/lib/facebooker/rails/facebook_pretty_errors.rb +14 -0
  76. data/lib/facebooker/rails/facebook_request_fix.rb +24 -0
  77. data/lib/facebooker/rails/facebook_session_handling.rb +69 -0
  78. data/lib/facebooker/rails/facebook_url_helper.rb +191 -0
  79. data/lib/facebooker/rails/facebook_url_rewriting.rb +39 -0
  80. data/lib/facebooker/rails/helpers.rb +642 -0
  81. data/lib/facebooker/rails/helpers/fb_connect.rb +34 -0
  82. data/lib/facebooker/rails/profile_publisher_extensions.rb +42 -0
  83. data/lib/facebooker/rails/publisher.rb +511 -0
  84. data/lib/facebooker/rails/routing.rb +49 -0
  85. data/lib/facebooker/rails/test_helpers.rb +88 -0
  86. data/lib/facebooker/rails/utilities.rb +22 -0
  87. data/lib/facebooker/server_cache.rb +24 -0
  88. data/lib/facebooker/service.rb +83 -0
  89. data/lib/facebooker/session.rb +564 -0
  90. data/lib/facebooker/version.rb +9 -0
  91. data/lib/net/http_multipart_post.rb +123 -0
  92. data/lib/tasks/facebooker.rake +18 -0
  93. data/lib/tasks/tunnel.rake +46 -0
  94. data/rails/init.rb +1 -0
  95. data/setup.rb +1585 -0
  96. data/templates/layout.erb +24 -0
  97. data/test/adapters_test.rb +98 -0
  98. data/test/batch_request_test.rb +82 -0
  99. data/test/event_test.rb +15 -0
  100. data/test/facebook_admin_test.rb +76 -0
  101. data/test/facebook_cache_test.rb +44 -0
  102. data/test/facebook_data_test.rb +86 -0
  103. data/test/facebooker_test.rb +855 -0
  104. data/test/fixtures/multipart_post_body_with_only_parameters.txt +33 -0
  105. data/test/fixtures/multipart_post_body_with_single_file.txt +38 -0
  106. data/test/fixtures/multipart_post_body_with_single_file_that_has_nil_key.txt +38 -0
  107. data/test/http_multipart_post_test.rb +54 -0
  108. data/test/logging_test.rb +43 -0
  109. data/test/model_test.rb +91 -0
  110. data/test/publisher_test.rb +458 -0
  111. data/test/rails_integration_test.rb +1221 -0
  112. data/test/session_test.rb +613 -0
  113. data/test/test_helper.rb +60 -0
  114. data/test/user_test.rb +270 -0
  115. metadata +185 -0
@@ -0,0 +1,34 @@
1
+ module Facebooker
2
+ module Rails
3
+ module Helpers
4
+ module FbConnect
5
+
6
+ def fb_connect_javascript_tag
7
+ javascript_include_tag "http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php"
8
+ end
9
+
10
+ def init_fb_connect(*required_features)
11
+ init_string = "FB.Facebook.init('#{Facebooker.api_key}','/xd_receiver.html');"
12
+ unless required_features.blank?
13
+ init_string = <<-FBML
14
+ Element.observe(window,'load', function() {
15
+ FB_RequireFeatures(#{required_features.to_json}, function() {
16
+ #{init_string}
17
+ });
18
+ });
19
+ FBML
20
+ end
21
+ javascript_tag init_string
22
+ end
23
+
24
+ def fb_login_button(callback=nil)
25
+ content_tag("fb:login-button",nil,(callback.nil? ? {} : {:onlogin=>callback}))
26
+ end
27
+
28
+ def fb_unconnected_friends_count
29
+ content_tag "fb:unconnected-friends-count",nil
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,42 @@
1
+ module Facebooker
2
+ module Rails
3
+ module ProfilePublisherExtensions
4
+
5
+ ##
6
+ # returns true if Facebook is requesting the interface for a profile publisher
7
+ def wants_interface?
8
+ params[:method] == "publisher_getInterface"
9
+ end
10
+
11
+ ##
12
+ # render the interface for a publisher.
13
+ # fbml is the content in string form. Use render_to_string to get the content from a template
14
+ # publish_enabled controlls whether the post form is active by default. If it isn't, you'll need to use fbjs to activate it
15
+ # comment_enabled controls whether to include a comment box
16
+ def render_publisher_interface(fbml,publish_enabled=true,comment_enabled=false)
17
+ render :json=>{:content=>{:fbml=>fbml,:publishEnabled=>publish_enabled,:commentEnabled=>comment_enabled},
18
+ :method=>"publisher_getInterface"}
19
+ end
20
+
21
+ # render an error while publishing the template
22
+ # This can be used for validation errors
23
+ def render_publisher_error(title,body)
24
+ render :json=>{:errorCode=>1,:errorTitle=>title,:errorMessage=>body}.to_json
25
+ end
26
+
27
+ # render the response for a feed. This takes a user_action object like those returned from the Rails Publisher
28
+ # For instance, AttackPublisher.create_attack(@attack)
29
+ # The template must have been registered previously
30
+ def render_publisher_response(user_action)
31
+ render :json=>{:content=> {
32
+ :feed=>{
33
+ :template_id=>user_action.template_id,
34
+ :template_data=>user_action.data
35
+ }
36
+ },
37
+ :method=>"publisher_getFeedStory"
38
+ }
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,511 @@
1
+ module Facebooker
2
+ module Rails
3
+ # ActionMailer like module for publishing Facbook messages
4
+ #
5
+ # To use, create a subclass and define methods
6
+ # Each method should start by calling send_as to specify the type of message
7
+ # Valid options are :email and :notification, :user_action, :profile, :ref
8
+ #
9
+ #
10
+ # Below is an example of each type
11
+ #
12
+ # class TestPublisher < Facebooker::Rails::Publisher
13
+ # # The new message templates are supported as well
14
+ # # First, create a method that contains your templates:
15
+ # # You may include multiple one line story templates and short story templates
16
+ # # but only one full story template
17
+ # # Your most specific template should be first
18
+ # #
19
+ # # Before using, you must register your template by calling register. For this example
20
+ # # You would call TestPublisher.register_publish_action
21
+ # # Registering the template will store the template id returned from Facebook in the
22
+ # # facebook_templates table that is created when you create your first publisher
23
+ # def publish_action_template
24
+ # one_line_story_template "{*actor*} did stuff with {*friend*}"
25
+ # one_line_story_template "{*actor*} did stuff"
26
+ # short_story_template "{*actor*} has a title {*friend*}", render(:partial=>"short_body")
27
+ # short_story_template "{*actor*} has a title", render(:partial=>"short_body")
28
+ # full_story_template "{*actor*} has a title {*friend*}", render(:partial=>"full_body")
29
+ # action_links action_link("My text {*template_var*}","{*link_url*}")
30
+ # end
31
+ #
32
+ # # To send a registered template, you need to create a method to set the data
33
+ # # The publisher will look up the template id from the facebook_templates table
34
+ # def publish_action(f)
35
+ # send_as :user_action
36
+ # from f
37
+ # story_size SHORT # or ONE_LINE or FULL
38
+ # data :friend=>"Mike"
39
+ # end
40
+ #
41
+ #
42
+ # # Provide a from user to send a general notification
43
+ # # if from is nil, this will send an announcement
44
+ # def notification(to,f)
45
+ # send_as :notification
46
+ # recipients to
47
+ # from f
48
+ # fbml "Not"
49
+ # end
50
+ #
51
+ # def email(to,f)
52
+ # send_as :email
53
+ # recipients to
54
+ # from f
55
+ # title "Email"
56
+ # fbml 'text'
57
+ # text fbml
58
+ # end
59
+ # # This will render the profile in /users/profile.erb
60
+ # # it will set @user to user_to_update in the template
61
+ # # The mobile profile will be rendered from the app/views/test_publisher/_mobile.erb
62
+ # # template
63
+ # def profile_update(user_to_update,user_with_session_to_use)
64
+ # send_as :profile
65
+ # from user_with_session_to_use
66
+ # to user_to_update
67
+ # profile render(:action=>"/users/profile",:assigns=>{:user=>user_to_update})
68
+ # profile_action "A string"
69
+ # mobile_profile render(:partial=>"mobile",:assigns=>{:user=>user_to_update})
70
+ # end
71
+ #
72
+ # # Update the given handle ref with the content from a
73
+ # # template
74
+ # def ref_update(user)
75
+ # send_as :ref
76
+ # from user
77
+ # fbml render(:action=>"/users/profile",:assigns=>{:user=>user_to_update})
78
+ # handle "a_ref_handle"
79
+ # end
80
+ #
81
+ #
82
+ # To send a message, use ActionMailer like semantics
83
+ # TestPublisher.deliver_action(@user)
84
+ #
85
+ # For testing, you may want to create an instance of the underlying message without sending it
86
+ # TestPublisher.create_action(@user)
87
+ # will create and return an instance of Facebooker::Feeds::Action
88
+ #
89
+ # Publisher makes many helpers available, including the linking and asset helpers
90
+ class Publisher
91
+
92
+ #story sizes from the Facebooker API
93
+ ONE_LINE=1
94
+ SHORT=2
95
+ FULL=4
96
+
97
+ def initialize
98
+ @controller = PublisherController.new
99
+ end
100
+
101
+ # use facebook options everywhere
102
+ def request_comes_from_facebook?
103
+ true
104
+ end
105
+
106
+ class FacebookTemplate < ::ActiveRecord::Base
107
+
108
+
109
+ cattr_accessor :template_cache
110
+ self.template_cache = {}
111
+
112
+ def self.inspect(*args)
113
+ "FacebookTemplate"
114
+ end
115
+
116
+ def template_changed?(hash)
117
+ if respond_to?(:content_hash)
118
+ content_hash != hash
119
+ else
120
+ false
121
+ end
122
+ end
123
+
124
+ class << self
125
+
126
+ def register(klass,method)
127
+ publisher = setup_publisher(klass,method)
128
+ template_id = Facebooker::Session.create.register_template_bundle(publisher.one_line_story_templates,publisher.short_story_templates,publisher.full_story_template,publisher.action_links)
129
+ template = find_or_initialize_by_template_name(template_name(klass,method))
130
+ template.bundle_id = template_id
131
+ template.content_hash = hashed_content(klass,method) if template.respond_to?(:content_hash)
132
+ template.save!
133
+ cache(klass,method,template)
134
+ template
135
+ end
136
+
137
+ def for_class_and_method(klass,method)
138
+ find_cached(klass,method)
139
+ end
140
+ def bundle_id_for_class_and_method(klass,method)
141
+ for_class_and_method(klass,method).bundle_id
142
+ end
143
+
144
+ def cache(klass,method,template)
145
+ template_cache[template_name(klass,method)] = template
146
+ end
147
+
148
+ def clear_cache!
149
+ self.template_cache = {}
150
+ end
151
+
152
+ def find_cached(klass,method)
153
+ template_cache[template_name(klass,method)] || find_in_db(klass,method)
154
+ end
155
+
156
+ def find_in_db(klass,method)
157
+ template = find_by_template_name(template_name(klass,method))
158
+ if template and template.template_changed?(hashed_content(klass,method))
159
+ template.destroy
160
+ template = nil
161
+ end
162
+
163
+ if template.nil?
164
+ template = register(klass,method)
165
+ end
166
+ template
167
+ end
168
+
169
+ def setup_publisher(klass,method)
170
+ publisher = klass.new
171
+ publisher.send method + '_template'
172
+ publisher
173
+ end
174
+
175
+ def hashed_content(klass, method)
176
+ publisher = setup_publisher(klass,method)
177
+ # sort the Hash elements (in the short_story and full_story) before generating MD5
178
+ Digest::MD5.hexdigest [publisher.one_line_story_templates,
179
+ (publisher.short_story_templates and publisher.short_story_templates.collect{|ss| ss.to_a.sort_by{|e| e[0]}}),
180
+ (publisher.full_story_template and publisher.full_story_template.to_a.sort_by{|e| e[0]})
181
+ ].to_json
182
+ end
183
+
184
+
185
+ def template_name(klass,method)
186
+ "#{klass.name}::#{method}"
187
+ end
188
+ end
189
+ end
190
+
191
+ class_inheritable_accessor :master_helper_module
192
+ attr_accessor :one_line_story_templates, :short_story_templates, :action_links
193
+
194
+ cattr_accessor :skip_registry
195
+ self.skip_registry = false
196
+
197
+
198
+ class InvalidSender < StandardError; end
199
+ class UnknownBodyType < StandardError; end
200
+ class UnspecifiedBodyType < StandardError; end
201
+ class Email
202
+ attr_accessor :title
203
+ attr_accessor :text
204
+ attr_accessor :fbml
205
+ end
206
+
207
+ class Notification
208
+ attr_accessor :fbml
209
+ end
210
+
211
+ class Profile
212
+ attr_accessor :profile
213
+ attr_accessor :profile_action
214
+ attr_accessor :mobile_profile
215
+ attr_accessor :profile_main
216
+ end
217
+ class Ref
218
+ attr_accessor :handle
219
+ attr_accessor :fbml
220
+ end
221
+ class UserAction
222
+ attr_accessor :data
223
+ attr_accessor :target_ids
224
+ attr_accessor :body_general
225
+ attr_accessor :template_id
226
+ attr_accessor :template_name
227
+ attr_accessor :story_size
228
+ def target_ids=(val)
229
+ @target_ids = val.is_a?(Array) ? val.join(",") : val
230
+ end
231
+ def data_hash
232
+ default_data = story_size.nil? ? {} : {:story_size=>story_size}
233
+ default_data.merge(data||{})
234
+ end
235
+ end
236
+
237
+ cattr_accessor :ignore_errors
238
+ attr_accessor :_body
239
+
240
+ def recipients(*args)
241
+ if args.size==0
242
+ @recipients
243
+ else
244
+ @recipients=args.first
245
+ end
246
+ end
247
+
248
+ def from(*args)
249
+ if args.size==0
250
+ @from
251
+ else
252
+ @from=args.first
253
+ end
254
+ end
255
+
256
+
257
+ def send_as(option)
258
+ self._body=case option
259
+ when :action
260
+ Facebooker::Feed::Action.new
261
+ when :story
262
+ Facebooker::Feed::Story.new
263
+ when :templatized_action
264
+ Facebooker::Feed::TemplatizedAction.new
265
+ when :notification
266
+ Notification.new
267
+ when :email
268
+ Email.new
269
+ when :profile
270
+ Profile.new
271
+ when :ref
272
+ Ref.new
273
+ when :user_action
274
+ UserAction.new
275
+ else
276
+ raise UnknownBodyType.new("Unknown type to publish")
277
+ end
278
+ end
279
+
280
+ def full_story_template(title=nil,body=nil,params={})
281
+ if title.nil?
282
+ @full_story_template
283
+ else
284
+ @full_story_template=params.merge(:template_title=>title, :template_body=>body)
285
+ end
286
+ end
287
+
288
+ def one_line_story_template(str)
289
+ @one_line_story_templates ||= []
290
+ @one_line_story_templates << str
291
+ end
292
+
293
+ def short_story_template(title,body,params={})
294
+ @short_story_templates ||= []
295
+ @short_story_templates << params.merge(:template_title=>title, :template_body=>body)
296
+ end
297
+
298
+ def action_links(*links)
299
+ if links.blank?
300
+ @action_links
301
+ else
302
+ @action_links = links
303
+ end
304
+ end
305
+
306
+ def method_missing(name,*args)
307
+ if args.size==1 and self._body.respond_to?("#{name}=")
308
+ self._body.send("#{name}=",*args)
309
+ elsif self._body.respond_to?(name)
310
+ self._body.send(name,*args)
311
+ else
312
+ super
313
+ end
314
+ end
315
+
316
+ def image(src,target)
317
+ {:src=>image_path(src),:href=> target.respond_to?(:to_str) ? target : url_for(target)}
318
+ end
319
+
320
+ def action_link(text,target)
321
+ {:text=>text, :href=>target}
322
+ end
323
+
324
+ def requires_from_user?(from,body)
325
+ ! (announcement_notification?(from,body) or ref_update?(body) or profile_update?(body))
326
+ end
327
+
328
+ def profile_update?(body)
329
+ body.is_a?(Profile)
330
+ end
331
+
332
+ def ref_update?(body)
333
+ body.is_a?(Ref)
334
+ end
335
+
336
+ def announcement_notification?(from,body)
337
+ from.nil? and body.is_a?(Notification)
338
+ end
339
+
340
+ def send_message(method)
341
+ @recipients = @recipients.is_a?(Array) ? @recipients : [@recipients]
342
+ if from.nil? and @recipients.size==1 and requires_from_user?(from,_body)
343
+ @from = @recipients.first
344
+ end
345
+ # notifications can
346
+ # omit the from address
347
+ raise InvalidSender.new("Sender must be a Facebooker::User") unless from.is_a?(Facebooker::User) || !requires_from_user?(from,_body)
348
+ case _body
349
+ when Facebooker::Feed::TemplatizedAction,Facebooker::Feed::Action
350
+ from.publish_action(_body)
351
+ when Facebooker::Feed::Story
352
+ @recipients.each {|r| r.publish_story(_body)}
353
+ when Notification
354
+ (from.nil? ? Facebooker::Session.create : from.session).send_notification(@recipients,_body.fbml)
355
+ when Email
356
+ from.session.send_email(@recipients,
357
+ _body.title,
358
+ _body.text,
359
+ _body.fbml)
360
+ when Profile
361
+ # If recipient and from aren't the same person, create a new user object using the
362
+ # userid from recipient and the session from from
363
+ @from = Facebooker::User.new(Facebooker::User.cast_to_facebook_id(@recipients.first),Facebooker::Session.create)
364
+ @from.set_profile_fbml(_body.profile, _body.mobile_profile, _body.profile_action, _body.profile_main)
365
+ when Ref
366
+ Facebooker::Session.create.server_cache.set_ref_handle(_body.handle,_body.fbml)
367
+ when UserAction
368
+ @from.session.publish_user_action(_body.template_id,_body.data_hash,_body.target_ids,_body.body_general)
369
+ else
370
+ raise UnspecifiedBodyType.new("You must specify a valid send_as")
371
+ end
372
+ end
373
+
374
+ # nodoc
375
+ # needed for actionview
376
+ def logger
377
+ RAILS_DEFAULT_LOGGER
378
+ end
379
+
380
+ # nodoc
381
+ # delegate to action view. Set up assigns and render
382
+ def render(opts)
383
+ opts = opts.dup
384
+ body = opts.delete(:assigns) || {}
385
+ initialize_template_class(body.dup.merge(:controller=>self)).render(opts)
386
+ end
387
+
388
+
389
+ def initialize_template_class(assigns)
390
+ template_root = "#{RAILS_ROOT}/app/views"
391
+ controller_root = File.join(template_root,self.class.controller_path)
392
+ #only do this on Rails 2.1
393
+ if ActionController::Base.respond_to?(:append_view_path)
394
+ # only add the view path once
395
+ ActionController::Base.append_view_path(controller_root) unless ActionController::Base.view_paths.include?(controller_root)
396
+ end
397
+ returning ActionView::Base.new([template_root,controller_root], assigns, self) do |template|
398
+ template.controller=self
399
+ template.extend(self.class.master_helper_module)
400
+ end
401
+ end
402
+
403
+
404
+ self.master_helper_module = Module.new
405
+ self.master_helper_module.module_eval do
406
+ # url_helper delegates to @controller,
407
+ # so we need to define that in the template
408
+ # we make it point to the publisher
409
+ include ActionView::Helpers::UrlHelper
410
+ include ActionView::Helpers::TextHelper
411
+ include ActionView::Helpers::TagHelper
412
+ include ActionView::Helpers::FormHelper
413
+ include ActionView::Helpers::FormTagHelper
414
+ include ActionView::Helpers::AssetTagHelper
415
+ include Facebooker::Rails::Helpers
416
+
417
+ #define this for the publisher views
418
+ def protect_against_forgery?
419
+ @paf ||= ActionController::Base.new.send(:protect_against_forgery?)
420
+ end
421
+
422
+ # url_for calls in publishers tend to want full paths
423
+ def url_for(options = {})
424
+ super(options.kind_of?(Hash) ? {:only_path => false}.update(options) : options)
425
+ end
426
+ end
427
+ ActionController::Routing::Routes.named_routes.install(self.master_helper_module)
428
+ include self.master_helper_module
429
+ class <<self
430
+
431
+ def register_all_templates
432
+ all_templates = instance_methods.grep(/_template$/) - %w(short_story_template full_story_template one_line_story_template)
433
+ all_templates.each do |template|
434
+ template_name=template.sub(/_template$/,"")
435
+ puts "Registering #{template_name}"
436
+ send("register_"+template_name)
437
+ end
438
+ end
439
+
440
+ def method_missing(name,*args)
441
+ should_send = false
442
+ method = ''
443
+ if md = /^create_(.*)$/.match(name.to_s)
444
+ method = md[1]
445
+ elsif md = /^deliver_(.*)$/.match(name.to_s)
446
+ method = md[1]
447
+ should_send = true
448
+ elsif md = /^register_(.*)$/.match(name.to_s)
449
+ return FacebookTemplate.register(self, md[1])
450
+ else
451
+ super
452
+ end
453
+
454
+ #now create the item
455
+ (publisher=new).send(method,*args)
456
+ case publisher._body
457
+ when UserAction
458
+ publisher._body.template_name = method
459
+ publisher._body.template_id = FacebookTemplate.bundle_id_for_class_and_method(self,method)
460
+ end
461
+
462
+ should_send ? publisher.send_message(method) : publisher._body
463
+ end
464
+
465
+ def default_url_options
466
+ {:host => Facebooker.canvas_server_base + Facebooker.facebook_path_prefix}
467
+ end
468
+
469
+ def controller_path
470
+ self.to_s.underscore
471
+ end
472
+
473
+ def helper(*args)
474
+ args.each do |arg|
475
+ case arg
476
+ when Symbol,String
477
+ add_template_helper("#{arg.to_s.classify}Helper".constantize)
478
+ when Module
479
+ add_template_helper(arg)
480
+ end
481
+ end
482
+ end
483
+
484
+ def add_template_helper(helper_module) #:nodoc:
485
+ master_helper_module.send :include,helper_module
486
+ include master_helper_module
487
+ end
488
+
489
+
490
+ def inherited(child)
491
+ super
492
+ child.master_helper_module=Module.new
493
+ child.master_helper_module.__send__(:include,self.master_helper_module)
494
+ child.send(:include, child.master_helper_module)
495
+ FacebookTemplate.clear_cache!
496
+ end
497
+
498
+ end
499
+ class PublisherController
500
+ include Facebooker::Rails::Publisher.master_helper_module
501
+ include ActionController::UrlWriter
502
+
503
+ def self.default_url_options(*args)
504
+ Facebooker::Rails::Publisher.default_url_options(*args)
505
+ end
506
+
507
+ end
508
+
509
+ end
510
+ end
511
+ end