taweili-facebooker 1.0.37

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 (135) hide show
  1. data/.autotest +15 -0
  2. data/CHANGELOG.rdoc +24 -0
  3. data/COPYING.rdoc +19 -0
  4. data/Manifest.txt +133 -0
  5. data/README.rdoc +104 -0
  6. data/Rakefile +85 -0
  7. data/TODO.rdoc +4 -0
  8. data/examples/desktop_login.rb +14 -0
  9. data/facebooker.gemspec +38 -0
  10. data/generators/facebook/facebook_generator.rb +14 -0
  11. data/generators/facebook/templates/config/facebooker.yml +49 -0
  12. data/generators/facebook/templates/public/javascripts/facebooker.js +83 -0
  13. data/generators/facebook_controller/USAGE +33 -0
  14. data/generators/facebook_controller/facebook_controller_generator.rb +40 -0
  15. data/generators/facebook_controller/templates/controller.rb +7 -0
  16. data/generators/facebook_controller/templates/functional_test.rb +11 -0
  17. data/generators/facebook_controller/templates/helper.rb +2 -0
  18. data/generators/facebook_controller/templates/view.fbml.erb +2 -0
  19. data/generators/facebook_controller/templates/view.html.erb +2 -0
  20. data/generators/facebook_publisher/facebook_publisher_generator.rb +14 -0
  21. data/generators/facebook_publisher/templates/create_facebook_templates.rb +15 -0
  22. data/generators/facebook_publisher/templates/publisher.rb +3 -0
  23. data/generators/facebook_scaffold/USAGE +27 -0
  24. data/generators/facebook_scaffold/facebook_scaffold_generator.rb +118 -0
  25. data/generators/facebook_scaffold/templates/controller.rb +93 -0
  26. data/generators/facebook_scaffold/templates/facebook_style.css +2579 -0
  27. data/generators/facebook_scaffold/templates/functional_test.rb +89 -0
  28. data/generators/facebook_scaffold/templates/helper.rb +2 -0
  29. data/generators/facebook_scaffold/templates/layout.fbml.erb +6 -0
  30. data/generators/facebook_scaffold/templates/layout.html.erb +17 -0
  31. data/generators/facebook_scaffold/templates/style.css +74 -0
  32. data/generators/facebook_scaffold/templates/view_edit.fbml.erb +13 -0
  33. data/generators/facebook_scaffold/templates/view_edit.html.erb +18 -0
  34. data/generators/facebook_scaffold/templates/view_index.fbml.erb +24 -0
  35. data/generators/facebook_scaffold/templates/view_index.html.erb +24 -0
  36. data/generators/facebook_scaffold/templates/view_new.fbml.erb +12 -0
  37. data/generators/facebook_scaffold/templates/view_new.html.erb +17 -0
  38. data/generators/facebook_scaffold/templates/view_show.fbml.erb +10 -0
  39. data/generators/facebook_scaffold/templates/view_show.html.erb +10 -0
  40. data/generators/publisher/publisher_generator.rb +14 -0
  41. data/generators/xd_receiver/templates/xd_receiver.html +10 -0
  42. data/generators/xd_receiver/xd_receiver_generator.rb +10 -0
  43. data/init.rb +25 -0
  44. data/install.rb +12 -0
  45. data/lib/facebooker/adapters/adapter_base.rb +91 -0
  46. data/lib/facebooker/adapters/bebo_adapter.rb +77 -0
  47. data/lib/facebooker/adapters/facebook_adapter.rb +52 -0
  48. data/lib/facebooker/admin.rb +42 -0
  49. data/lib/facebooker/batch_request.rb +45 -0
  50. data/lib/facebooker/data.rb +57 -0
  51. data/lib/facebooker/feed.rb +78 -0
  52. data/lib/facebooker/logging.rb +44 -0
  53. data/lib/facebooker/mobile.rb +20 -0
  54. data/lib/facebooker/mock/service.rb +50 -0
  55. data/lib/facebooker/mock/session.rb +18 -0
  56. data/lib/facebooker/model.rb +139 -0
  57. data/lib/facebooker/models/affiliation.rb +10 -0
  58. data/lib/facebooker/models/album.rb +11 -0
  59. data/lib/facebooker/models/applicationproperties.rb +39 -0
  60. data/lib/facebooker/models/applicationrestrictions.rb +10 -0
  61. data/lib/facebooker/models/cookie.rb +10 -0
  62. data/lib/facebooker/models/education_info.rb +11 -0
  63. data/lib/facebooker/models/event.rb +28 -0
  64. data/lib/facebooker/models/friend_list.rb +16 -0
  65. data/lib/facebooker/models/group.rb +36 -0
  66. data/lib/facebooker/models/info_item.rb +10 -0
  67. data/lib/facebooker/models/info_section.rb +10 -0
  68. data/lib/facebooker/models/location.rb +8 -0
  69. data/lib/facebooker/models/notifications.rb +17 -0
  70. data/lib/facebooker/models/page.rb +28 -0
  71. data/lib/facebooker/models/photo.rb +19 -0
  72. data/lib/facebooker/models/tag.rb +12 -0
  73. data/lib/facebooker/models/user.rb +497 -0
  74. data/lib/facebooker/models/video.rb +9 -0
  75. data/lib/facebooker/models/work_info.rb +10 -0
  76. data/lib/facebooker/parser.rb +650 -0
  77. data/lib/facebooker/rails/backwards_compatible_param_checks.rb +31 -0
  78. data/lib/facebooker/rails/controller.rb +337 -0
  79. data/lib/facebooker/rails/cucumber/world.rb +46 -0
  80. data/lib/facebooker/rails/cucumber.rb +28 -0
  81. data/lib/facebooker/rails/extensions/action_controller.rb +48 -0
  82. data/lib/facebooker/rails/extensions/rack_setup.rb +6 -0
  83. data/lib/facebooker/rails/extensions/routing.rb +15 -0
  84. data/lib/facebooker/rails/facebook_form_builder.rb +112 -0
  85. data/lib/facebooker/rails/facebook_pretty_errors.rb +22 -0
  86. data/lib/facebooker/rails/facebook_request_fix.rb +30 -0
  87. data/lib/facebooker/rails/facebook_request_fix_2-3.rb +31 -0
  88. data/lib/facebooker/rails/facebook_session_handling.rb +68 -0
  89. data/lib/facebooker/rails/facebook_url_helper.rb +192 -0
  90. data/lib/facebooker/rails/facebook_url_rewriting.rb +60 -0
  91. data/lib/facebooker/rails/helpers/fb_connect.rb +118 -0
  92. data/lib/facebooker/rails/helpers.rb +780 -0
  93. data/lib/facebooker/rails/integration_session.rb +38 -0
  94. data/lib/facebooker/rails/profile_publisher_extensions.rb +42 -0
  95. data/lib/facebooker/rails/publisher.rb +554 -0
  96. data/lib/facebooker/rails/routing.rb +49 -0
  97. data/lib/facebooker/rails/test_helpers.rb +68 -0
  98. data/lib/facebooker/rails/utilities.rb +22 -0
  99. data/lib/facebooker/server_cache.rb +24 -0
  100. data/lib/facebooker/service.rb +102 -0
  101. data/lib/facebooker/session.rb +606 -0
  102. data/lib/facebooker/version.rb +9 -0
  103. data/lib/facebooker.rb +180 -0
  104. data/lib/net/http_multipart_post.rb +123 -0
  105. data/lib/rack/facebook.rb +77 -0
  106. data/lib/tasks/facebooker.rake +18 -0
  107. data/lib/tasks/tunnel.rake +46 -0
  108. data/rails/init.rb +1 -0
  109. data/setup.rb +1585 -0
  110. data/templates/layout.erb +24 -0
  111. data/test/facebooker/adapters_test.rb +96 -0
  112. data/test/facebooker/admin_test.rb +102 -0
  113. data/test/facebooker/batch_request_test.rb +83 -0
  114. data/test/facebooker/data_test.rb +86 -0
  115. data/test/facebooker/logging_test.rb +43 -0
  116. data/test/facebooker/mobile_test.rb +45 -0
  117. data/test/facebooker/model_test.rb +133 -0
  118. data/test/facebooker/models/event_test.rb +15 -0
  119. data/test/facebooker/models/photo_test.rb +16 -0
  120. data/test/facebooker/models/user_test.rb +343 -0
  121. data/test/facebooker/rails/facebook_request_fix_2-3_test.rb +24 -0
  122. data/test/facebooker/rails/facebook_url_rewriting_test.rb +39 -0
  123. data/test/facebooker/rails/publisher_test.rb +481 -0
  124. data/test/facebooker/rails_integration_test.rb +1398 -0
  125. data/test/facebooker/server_cache_test.rb +44 -0
  126. data/test/facebooker/session_test.rb +614 -0
  127. data/test/facebooker_test.rb +951 -0
  128. data/test/fixtures/multipart_post_body_with_only_parameters.txt +33 -0
  129. data/test/fixtures/multipart_post_body_with_single_file.txt +38 -0
  130. data/test/fixtures/multipart_post_body_with_single_file_that_has_nil_key.txt +38 -0
  131. data/test/net/http_multipart_post_test.rb +52 -0
  132. data/test/rack/facebook_test.rb +61 -0
  133. data/test/rails_test_helper.rb +27 -0
  134. data/test/test_helper.rb +74 -0
  135. metadata +232 -0
data/lib/facebooker.rb ADDED
@@ -0,0 +1,180 @@
1
+ unless defined?(ActiveSupport) and defined?(ActiveSupport::JSON)
2
+ require 'json'
3
+ module Facebooker
4
+ def self.json_decode(str)
5
+ JSON.parse(str)
6
+ end
7
+
8
+ def self.json_encode(o)
9
+ JSON.dump(o)
10
+ end
11
+ end
12
+ else
13
+ module Facebooker
14
+ def self.json_decode(str)
15
+ ActiveSupport::JSON.decode(str)
16
+ end
17
+
18
+ def self.json_encode(o)
19
+ ActiveSupport::JSON.encode(o)
20
+ end
21
+ end
22
+ end
23
+
24
+ require 'zlib'
25
+ require 'digest/md5'
26
+
27
+ module Facebooker
28
+
29
+ @facebooker_configuration = {}
30
+ @current_adapter = nil
31
+ @set_asset_host_to_callback_url = true
32
+ @path_prefix = nil
33
+ @use_curl = false
34
+
35
+ class << self
36
+
37
+ def load_configuration(facebooker_yaml_file)
38
+ if File.exist?(facebooker_yaml_file)
39
+ if defined? RAILS_ENV
40
+ config = YAML.load_file(facebooker_yaml_file)[RAILS_ENV]
41
+ else
42
+ config = YAML.load_file(facebooker_yaml_file)
43
+ end
44
+ apply_configuration(config)
45
+ end
46
+ end
47
+
48
+ # Sets the Facebook environment based on a hash of options.
49
+ # By default the hash passed in is loaded from facebooker.yml, but it can also be passed in
50
+ # manually every request to run multiple Facebook apps off one Rails app.
51
+ def apply_configuration(config)
52
+ ENV['FACEBOOK_API_KEY'] = config['api_key']
53
+ ENV['FACEBOOK_SECRET_KEY'] = config['secret_key']
54
+ ENV['FACEBOOKER_RELATIVE_URL_ROOT'] = config['canvas_page_name']
55
+ ENV['FACEBOOKER_API'] = config['api']
56
+ if config.has_key?('set_asset_host_to_callback_url')
57
+ Facebooker.set_asset_host_to_callback_url = config['set_asset_host_to_callback_url']
58
+ end
59
+ if Object.const_defined?("ActionController") and Facebooker.set_asset_host_to_callback_url
60
+ ActionController::Base.asset_host = config['callback_url']
61
+ end
62
+ Facebooker.timeout = config['timeout']
63
+ @facebooker_configuration = config
64
+ end
65
+
66
+ def facebooker_config
67
+ @facebooker_configuration
68
+ end
69
+
70
+ # TODO: This should be converted to attr_accessor, but we need to
71
+ # get all the require statements at the top of the file to work.
72
+
73
+ # Set the current adapter
74
+ attr_writer :current_adapter
75
+
76
+ # Get the current adapter
77
+ def current_adapter
78
+ @current_adapter || Facebooker::AdapterBase.default_adapter
79
+ end
80
+
81
+ def load_adapter(params)
82
+ self.current_adapter = Facebooker::AdapterBase.load_adapter(params)
83
+ end
84
+
85
+ def facebook_path_prefix=(path)
86
+ current_adapter.facebook_path_prefix = path
87
+ end
88
+
89
+ # Default is canvas_page_name in yml file
90
+ def facebook_path_prefix
91
+ current_adapter.facebook_path_prefix
92
+ end
93
+
94
+ def is_for?(application_container)
95
+ current_adapter.is_for?(application_container)
96
+ end
97
+
98
+ attr_accessor :set_asset_host_to_callback_url
99
+ attr_accessor :use_curl
100
+ alias :use_curl? :use_curl
101
+
102
+ def timeout=(val)
103
+ @timeout = val.to_i
104
+ end
105
+
106
+ def timeout
107
+ @timeout
108
+ end
109
+
110
+ [:api_key,:secret_key, :www_server_base_url,:login_url_base,:install_url_base,:api_rest_path,:api_server_base,:api_server_base_url,:canvas_server_base, :video_server_base].each do |delegated_method|
111
+ define_method(delegated_method){ return current_adapter.send(delegated_method)}
112
+ end
113
+
114
+
115
+ attr_reader :path_prefix
116
+
117
+
118
+ # Set the asset path to the canvas path for just this one request
119
+ # by definition, we will make this a canvas request
120
+ def with_asset_path_for_canvas
121
+ original_asset_host = ActionController::Base.asset_host
122
+ begin
123
+ ActionController::Base.asset_host = Facebooker.api_server_base_url
124
+ request_for_canvas(true) do
125
+ yield
126
+ end
127
+ ensure
128
+ ActionController::Base.asset_host = original_asset_host
129
+ end
130
+ end
131
+
132
+ # If this request is_canvas_request
133
+ # then use the application name as the url root
134
+ def request_for_canvas(is_canvas_request)
135
+ original_path_prefix = @path_prefix
136
+ begin
137
+ @path_prefix = facebook_path_prefix if is_canvas_request
138
+ yield
139
+ ensure
140
+ @path_prefix = original_path_prefix
141
+ end
142
+ end
143
+ end
144
+ end
145
+
146
+ require 'facebooker/batch_request'
147
+ require 'facebooker/feed'
148
+ require 'facebooker/logging'
149
+ require 'facebooker/model'
150
+ require 'facebooker/parser'
151
+ require 'facebooker/service'
152
+ require 'facebooker/server_cache'
153
+ require 'facebooker/data'
154
+ require 'facebooker/admin'
155
+ require 'facebooker/mobile'
156
+ require 'facebooker/session'
157
+ require 'facebooker/version'
158
+ require 'facebooker/models/location'
159
+ require 'facebooker/models/affiliation'
160
+ require 'facebooker/models/album'
161
+ require 'facebooker/models/education_info'
162
+ require 'facebooker/models/work_info'
163
+ require 'facebooker/models/event'
164
+ require 'facebooker/models/group'
165
+ require 'facebooker/models/notifications'
166
+ require 'facebooker/models/page'
167
+ require 'facebooker/models/photo'
168
+ require 'facebooker/models/cookie'
169
+ require 'facebooker/models/applicationproperties'
170
+ require 'facebooker/models/applicationrestrictions'
171
+ require 'facebooker/models/tag'
172
+ require 'facebooker/models/user'
173
+ require 'facebooker/models/info_item'
174
+ require 'facebooker/models/info_section'
175
+ require 'facebooker/models/permission'
176
+ require 'facebooker/models/friend_list'
177
+ require 'facebooker/models/video'
178
+ require 'facebooker/adapters/adapter_base'
179
+ require 'facebooker/adapters/facebook_adapter'
180
+ require 'facebooker/adapters/bebo_adapter'
@@ -0,0 +1,123 @@
1
+ require 'net/http'
2
+
3
+ module Net
4
+ class HTTP
5
+ class << self
6
+ def post_multipart_form(url, params)
7
+ MultipartPost.new(url, params).post
8
+ end
9
+ end
10
+
11
+ class MultipartPostFile
12
+ def initialize(filename=nil, content_type=nil, data=nil)
13
+ @filename = filename
14
+ @content_type = content_type
15
+ @data = data
16
+ end
17
+
18
+ attr_accessor :filename
19
+ attr_accessor :content_type
20
+ attr_accessor :data
21
+ end
22
+
23
+ class MultipartPost
24
+ def initialize(url, params)
25
+ @url = url
26
+ @multipart_post_files = extract_file_parameters_from(params)
27
+ @params = extract_non_file_parameters_from(params)
28
+ end
29
+
30
+ def post
31
+ req = Post.new(url.path)
32
+ req.body = body
33
+ req.content_type = content_type
34
+ req.basic_auth url.user, url.password if url.user
35
+ Net::HTTP.new(url.host, url.port).start {|http|
36
+ http.request(req)
37
+ }
38
+ end
39
+
40
+ BOUNDARY = "MichaelNiessnerIsSuperDuperAwesome"
41
+
42
+ protected
43
+ attr_reader :url, :params, :multipart_post_files
44
+
45
+ def extract_file_parameters_from(hash)
46
+ hash.reject{|key, value| !multipart_post_file?(value)}
47
+ end
48
+
49
+ def extract_non_file_parameters_from(hash)
50
+ hash.reject{|key, value| multipart_post_file?(value)}
51
+ end
52
+
53
+ def multipart_post_file?(object)
54
+ object.respond_to?(:content_type) &&
55
+ object.respond_to?(:data) &&
56
+ object.respond_to?(:filename)
57
+ end
58
+
59
+ def content_type
60
+ "multipart/form-data; boundary=#{BOUNDARY}"
61
+ end
62
+
63
+ def body
64
+ encode_parameters + encode_multipart_post_files + final_boundary
65
+ end
66
+
67
+ def encode_multipart_post_files
68
+ return "" if multipart_post_files.empty?
69
+ if multipart_post_files.size == 1
70
+ name = multipart_post_files.keys.first
71
+ file = multipart_post_files.values.first
72
+ encode_multipart_post_file(name, file)
73
+ else
74
+ raise "Currently more than 1 file upload is not supported."
75
+ end
76
+ end
77
+
78
+ def encode_multipart_post_file(name, multipart_post_file)
79
+ parameter_boundary +
80
+ disposition_with_filename(name, multipart_post_file.filename) +
81
+ file_content_type(multipart_post_file.content_type) +
82
+ multipart_post_file.data +
83
+ "\r\n"
84
+ end
85
+
86
+ def encode_parameters
87
+ params.sort_by{|key, value| key.to_s}.map{|key, value| encode_parameter(key, value)}.join
88
+ end
89
+
90
+ def encode_parameter(key, value)
91
+ parameter_boundary + disposition_with_name(key) + value.to_s + "\r\n"
92
+ end
93
+
94
+ def file_content_type(string)
95
+ "Content-Type: #{string}\r\n\r\n"
96
+ end
97
+
98
+ def disposition_with_filename(name, filename)
99
+ if name.nil?
100
+ disposition("filename=\"#{filename}\"")
101
+ else
102
+ disposition("name=\"#{name}\"; filename=\"#{filename}\"")
103
+ end
104
+ end
105
+
106
+ def disposition_with_name(name)
107
+ disposition("name=\"#{name}\"\r\n")
108
+ end
109
+
110
+ def disposition(attribute)
111
+ "Content-Disposition: form-data; #{attribute}\r\n"
112
+ end
113
+
114
+ def parameter_boundary
115
+ "--#{BOUNDARY}\r\n"
116
+ end
117
+
118
+ def final_boundary
119
+ "--#{BOUNDARY}--\r\n"
120
+ end
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,77 @@
1
+ module Rack
2
+ # This Rack middleware checks the signature of Facebook params, and
3
+ # converts them to Ruby objects when appropiate. Also, it converts
4
+ # the request method from the Facebook POST to the original HTTP
5
+ # method used by the client.
6
+ #
7
+ # If the signature is wrong, it returns a "400 Invalid Facebook Signature".
8
+ #
9
+ # Optionally, it can take a block that receives the Rack environment
10
+ # and returns a value that evaluates to true when we want the middleware to
11
+ # be executed for the specific request.
12
+ #
13
+ # == Usage
14
+ #
15
+ # In your config.ru:
16
+ #
17
+ # require 'rack/facebook'
18
+ # use Rack::Facebook, "my_facebook_secret_key"
19
+ #
20
+ # Using a block condition:
21
+ #
22
+ # use Rack::Facebook, "my_facebook_secret_key" do |env|
23
+ # env['REQUEST_URI'] =~ /^\/facebook_only/
24
+ # end
25
+ #
26
+ class Facebook
27
+ def initialize(app, secret_key, &condition)
28
+ @app = app
29
+ @secret_key = secret_key
30
+ @condition = condition
31
+ end
32
+
33
+ def call(env)
34
+ if @condition.nil? || @condition.call(env)
35
+ request = Rack::Request.new(env)
36
+ fb_params = extract_fb_sig_params(request.POST)
37
+ unless fb_params.empty?
38
+ unless signature_is_valid?(fb_params, request.POST['fb_sig'])
39
+ return Rack::Response.new(["Invalid Facebook signature"], 400).finish
40
+ end
41
+ env['REQUEST_METHOD'] = fb_params["request_method"] if fb_params["request_method"]
42
+ convert_parameters!(request.POST)
43
+ end
44
+ end
45
+ @app.call(env)
46
+ end
47
+
48
+ private
49
+
50
+ def extract_fb_sig_params(params)
51
+ params.inject({}) do |collection, (param, value)|
52
+ collection[param.sub(/^fb_sig_/, '')] = value if param[0,7] == 'fb_sig_'
53
+ collection
54
+ end
55
+ end
56
+
57
+ def signature_is_valid?(fb_params, actual_sig)
58
+ raw_string = fb_params.map{ |*args| args.join('=') }.sort.join
59
+ expected_signature = Digest::MD5.hexdigest([raw_string, @secret_key].join)
60
+ actual_sig == expected_signature
61
+ end
62
+
63
+ def convert_parameters!(params)
64
+
65
+ params.each do |key, value|
66
+ case key
67
+ when 'fb_sig_added', 'fb_sig_in_canvas', 'fb_sig_in_new_facebook', 'fb_sig_position_fix', 'fb_sig_is_ajax'
68
+ params[key] = value == "1"
69
+ when 'fb_sig_expires', 'fb_sig_profile_update_time', 'fb_sig_time'
70
+ params[key] = value == "0" ? nil : Time.at(value.to_f)
71
+ when 'fb_sig_friends'
72
+ params[key] = value.split(',')
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,18 @@
1
+ require 'fileutils'
2
+
3
+ namespace :facebooker do
4
+
5
+ desc "Create a basic facebooker.yml configuration file"
6
+ task :setup => :environment do
7
+ facebook_config = File.join(RAILS_ROOT,"config","facebooker.yml")
8
+ unless File.exist?(facebook_config)
9
+ FileUtils.cp File.join(RAILS_ROOT,"vendor", "plugins", "facebooker", "facebooker.yml.tpl"), facebook_config
10
+ puts "Ensure 'GatewayPorts yes' is enabled in the remote development server's sshd config when using any of the facebooker:tunnel:*' rake tasks"
11
+ puts "Configuration created in #{RAILS_ROOT}/config/facebooker.yml"
12
+ else
13
+ puts "#{RAILS_ROOT}/config/facebooker.yml already exists"
14
+ end
15
+ end
16
+
17
+ end
18
+
@@ -0,0 +1,46 @@
1
+ namespace :facebooker do
2
+
3
+ tunnel_ns = namespace :tunnel do
4
+ # Courtesy of Christopher Haupt
5
+ # http://www.BuildingWebApps.com
6
+ # http://www.LearningRails.com
7
+ desc "Create a reverse ssh tunnel from a public server to a private development server."
8
+ task :start => [ :environment, :config ] do
9
+ puts @notification
10
+ system @ssh_command
11
+ end
12
+
13
+ desc "Create a reverse ssh tunnel in the background. Requires ssh keys to be setup."
14
+ task :background_start => [ :environment, :config ] do
15
+ puts @notification
16
+ system "#{@ssh_command} > /dev/null 2>&1 &"
17
+ end
18
+
19
+ # Adapted from Evan Weaver: http://blog.evanweaver.com/articles/2007/07/13/developing-a-facebook-app-locally/
20
+ desc "Check if reverse tunnel is running"
21
+ task :status => [ :environment, :config ] do
22
+ if `ssh #{@public_host} -l #{@public_host_username} netstat -an | egrep "tcp.*:#{@public_port}.*LISTEN" | wc`.to_i > 0
23
+ puts "Seems ok"
24
+ else
25
+ puts "Down"
26
+ end
27
+ end
28
+
29
+ task :config => :environment do
30
+ facebook_config = File.dirname(__FILE__) + '/../../../../../config/facebooker.yml'
31
+ FACEBOOKER = YAML.load_file(facebook_config)[RAILS_ENV]
32
+ @public_host_username = FACEBOOKER['tunnel']['public_host_username']
33
+ @public_host = FACEBOOKER['tunnel']['public_host']
34
+ @public_port = FACEBOOKER['tunnel']['public_port']
35
+ @local_port = FACEBOOKER['tunnel']['local_port']
36
+ @ssh_port = FACEBOOKER['tunnel']['ssh_port'] || 22
37
+ @server_alive_interval = FACEBOOKER['tunnel']['server_alive_interval'] || 0
38
+ @notification = "Starting tunnel #{@public_host}:#{@public_port} to 0.0.0.0:#{@local_port}"
39
+ @notification << " using SSH port #{@ssh_port}" unless @ssh_port == 22
40
+ # "GatewayPorts yes" needs to be enabled in the remote's sshd config
41
+ @ssh_command = %Q[ssh -v -p #{@ssh_port} -nNT4 -o "ServerAliveInterval #{@server_alive_interval}" -R *:#{@public_port}:localhost:#{@local_port} #{@public_host_username}@#{@public_host}]
42
+ end
43
+ end
44
+ desc "Create a reverse ssh tunnel from a public server to a private development server."
45
+ task :tunnel => tunnel_ns[:start]
46
+ end
data/rails/init.rb ADDED
@@ -0,0 +1 @@
1
+ require File.join(File.dirname(__FILE__),'../init.rb')