simple-fluther 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +20 -0
- data/README.textile +85 -0
- data/lib/simple-fluther.rb +6 -0
- data/lib/simple-fluther/config.rb +36 -0
- data/lib/simple-fluther/controller_methods.rb +91 -0
- metadata +84 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2009 Plataforma Tecnologia. http://blog.plataformatec.com.br
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.textile
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
h1. Fluther Ruby/Rails Client
|
2
|
+
|
3
|
+
h2. Introduction
|
4
|
+
|
5
|
+
This gem provides an interface to the "Fluther discussion service":http://www.fluther.com/. It is intended to be included into your controller (i.e. FlutherController) and called as a @before_filter@. It handles proxying requests to Fluther and returning the response so that it can be included in your web application.
|
6
|
+
|
7
|
+
It's based on the original "Fluther gem":http://github.com/Conceivian/Fluther but modified to not require Warden or Rack-integration.
|
8
|
+
|
9
|
+
h2. Installation
|
10
|
+
|
11
|
+
* Add the @simple-fluther@ gem to your application (i.e. in @Gemfile@ or @environment.rb@).
|
12
|
+
|
13
|
+
* Create an initializer (e.g. @config/initializers/fluther.rb@) that sets the following configuration:
|
14
|
+
|
15
|
+
<pre>
|
16
|
+
class SimpleFluther::Config
|
17
|
+
# hostname of the Fluther server for this environment (provided by Fluther)
|
18
|
+
fluther_host 'fstage.fluther.com'
|
19
|
+
|
20
|
+
# the route for your app
|
21
|
+
prefix '/qna'
|
22
|
+
|
23
|
+
# federated API key (provided by Fluther)
|
24
|
+
app_key '2b6a0009c414c53e3d4fa8f8c3134d59'
|
25
|
+
|
26
|
+
# what method to call in the controller to get the current user model
|
27
|
+
method_to_get_current_user :current_user
|
28
|
+
|
29
|
+
# mapping of attributes in the User model to the Fluther user
|
30
|
+
user_fields :id => :id, :name => :name, :email => :email # (defaults)
|
31
|
+
end
|
32
|
+
</pre>
|
33
|
+
|
34
|
+
|
35
|
+
h2. Rails Integration
|
36
|
+
|
37
|
+
In your controller, include the module @Fluther::ControllerMethods@ and add the @make_fluther_request@ @before_filter@ to your target action.
|
38
|
+
|
39
|
+
The proxy provides three Rack variables that include the Fluther response: @fluther.header@, @fluther.title@, and
|
40
|
+
@fluther.response@. The first two (may) contain HTML blocks which should be inserted into the page @<head>@ and @<title>@ blocks,
|
41
|
+
respectively, and the third is the HTML for the Fluther widget itself.
|
42
|
+
|
43
|
+
To integrate the response into your application, you should add an action which is routed from the same path as the Fluther proxy.
|
44
|
+
For this example, we assume the controller is @MainController@, the action is @fluther@, and as above, it is mounted at @/qna@.
|
45
|
+
Also, we assume that the application layout includes @yield(:head)@ in the @<head>@ block:
|
46
|
+
|
47
|
+
<pre>
|
48
|
+
# config/routes.rb
|
49
|
+
map.fluther '/qna/*_', :controller => 'fluther', :action => 'index'
|
50
|
+
</pre>
|
51
|
+
|
52
|
+
Your controller might look something like this:
|
53
|
+
|
54
|
+
<pre>
|
55
|
+
# app/controllers/fluther_controller.rb
|
56
|
+
class FlutherController < ApplicationController
|
57
|
+
include SimpleFluther::ControllerMethods
|
58
|
+
before_filter :make_fluther_request, :only => :index
|
59
|
+
|
60
|
+
def index
|
61
|
+
end
|
62
|
+
end
|
63
|
+
</pre>
|
64
|
+
|
65
|
+
<pre>
|
66
|
+
# app/views/fluther/index.html.erb
|
67
|
+
<%
|
68
|
+
if (header = request.env['fluther.header']).present?
|
69
|
+
content_for :head, header
|
70
|
+
end
|
71
|
+
if (title = request.env['fluther.title']).present?
|
72
|
+
content_for :head, content_tag(:title, title)
|
73
|
+
end
|
74
|
+
%>
|
75
|
+
<%= request.env['fluther.response'] -%>
|
76
|
+
</pre>
|
77
|
+
|
78
|
+
You should now be able to start your application, navigate to http://localhost:300/qna and see the Fluther page.
|
79
|
+
|
80
|
+
h2. Credits
|
81
|
+
|
82
|
+
Based on original "Fluther gem":http://github.com/Conceivian/Fluther by Steve Sloan.
|
83
|
+
|
84
|
+
* Author: "Justin Chen":mailto:justin@menuism.com
|
85
|
+
* License: MIT
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module SimpleFluther
|
2
|
+
class Config
|
3
|
+
def self.prefix( *args )
|
4
|
+
@@prefix = nil unless defined? @@prefix
|
5
|
+
return @@prefix if args.empty?
|
6
|
+
@@prefix = args.first
|
7
|
+
@@prefix = "/#{@@prefix}" unless @@prefix.starts_with?('/')
|
8
|
+
@@prefix
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.fluther_host( *args )
|
12
|
+
@@fluther_host = nil unless defined? @@fluther_host
|
13
|
+
return @@fluther_host if args.empty?
|
14
|
+
@@fluther_host = args.first
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.app_key( *args )
|
18
|
+
@@app_key = nil unless defined? @@app_key
|
19
|
+
return @@app_key if args.empty?
|
20
|
+
@@app_key = args.first
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.method_to_get_current_user( *args)
|
24
|
+
@@method_to_get_current_user = nil unless defined? @@method_to_get_current_user
|
25
|
+
return @@method_to_get_current_user if args.empty?
|
26
|
+
@@method_to_get_current_user = args.first
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.user_fields( *args )
|
30
|
+
@@user_fields = { :id => :id, :name => :name, :email => :email } unless defined? @@user_fields
|
31
|
+
return @@user_fields if args.empty?
|
32
|
+
@@user_fields.update args.first
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'em-http-request'
|
2
|
+
|
3
|
+
module SimpleFluther
|
4
|
+
module ControllerMethods
|
5
|
+
def make_fluther_request
|
6
|
+
setup_fluther_user
|
7
|
+
return exec_request
|
8
|
+
end
|
9
|
+
|
10
|
+
def setup_fluther_user
|
11
|
+
@fluther_user = {}
|
12
|
+
if user = self.send(SimpleFluther::Config.method_to_get_current_user) rescue nil
|
13
|
+
SimpleFluther::Config.user_fields.each { |dest, src| @fluther_user[dest] = user.send(src).to_s }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def build_request
|
18
|
+
fluther_params = request.params.dup.update(
|
19
|
+
:fed_key => SimpleFluther::Config.app_key
|
20
|
+
)
|
21
|
+
fluther_params[:fed_sessionid] = request.cookies['fed_sessionid'] if request.cookies['fed_sessionid']
|
22
|
+
if @fluther_user.present?
|
23
|
+
fluther_params[:fed_uid] = @fluther_user[:id].to_s
|
24
|
+
fluther_params[:fed_username] = @fluther_user[:name].to_s
|
25
|
+
fluther_params[:fed_email] = @fluther_user[:email].to_s
|
26
|
+
end
|
27
|
+
|
28
|
+
options = {
|
29
|
+
:redirects => 0,
|
30
|
+
:timeout => 10,
|
31
|
+
:head => {
|
32
|
+
'User-Agent' => "Fluther Federated Client #{SimpleFluther::ClientVersion} (Ruby)",
|
33
|
+
'X-Forwarded-For' => request.env['REMOTE_ADDR'],
|
34
|
+
'X-Forwarded-Host' => request.env['HTTP_HOST'],
|
35
|
+
'X-Forwarded-User-Agent' => request.user_agent
|
36
|
+
}
|
37
|
+
}
|
38
|
+
options[:head]['X-Requested-With'] = request.env['HTTP_X_REQUESTED_WITH'] if request.env['HTTP_X_REQUESTED_WITH']
|
39
|
+
options[request.post? ? :body : :query] = fluther_params
|
40
|
+
|
41
|
+
path = request.path.sub( %r{^#{SimpleFluther::Config.prefix}}, '' )
|
42
|
+
path = '/' + path unless path.starts_with?('/')
|
43
|
+
path = path + '/' unless path.ends_with?('/')
|
44
|
+
url = "#{request.scheme}://#{SimpleFluther::Config.fluther_host}#{path}"
|
45
|
+
|
46
|
+
Rails.logger.debug request.request_method
|
47
|
+
Rails.logger.debug url
|
48
|
+
Rails.logger.debug options
|
49
|
+
|
50
|
+
EventMachine::HttpRequest.new( url ).send( request.request_method, options )
|
51
|
+
end
|
52
|
+
|
53
|
+
def exec_request
|
54
|
+
result = nil
|
55
|
+
em_running = EM.reactor_running?
|
56
|
+
EM.run do
|
57
|
+
fluther = build_request
|
58
|
+
fluther.callback do
|
59
|
+
result = handle_response fluther
|
60
|
+
EM.stop
|
61
|
+
end
|
62
|
+
end
|
63
|
+
result
|
64
|
+
end
|
65
|
+
|
66
|
+
def handle_response( fluther )
|
67
|
+
Rails.logger.debug "Fluther HTTP Response Code: #{fluther.response_header.status}"
|
68
|
+
Rails.logger.debug fluther.response_header
|
69
|
+
type_header = fluther.response_header['CONTENT_TYPE']
|
70
|
+
content_type = type_header.split(';')[0] || 'text/html'
|
71
|
+
|
72
|
+
result = if [301, 302].include?( fluther.response_header.status )
|
73
|
+
redirect_to fluther.response_header['LOCATION'], :status => fluther.response_header.status
|
74
|
+
false
|
75
|
+
elsif request.xhr? || (content_type != 'text/html')
|
76
|
+
Rails.logger.debug "AJAX?"
|
77
|
+
render :text => fluther.response, :layout => false
|
78
|
+
# [ fluther.response_header.status, {'Content-Type' => type_header}, [fluther.response] ]
|
79
|
+
true
|
80
|
+
else
|
81
|
+
fluther.response.html_safe if fluther.response.respond_to?(:html_safe)
|
82
|
+
request.env['fluther.response'] = fluther.response
|
83
|
+
request.env['fluther.title'] = fluther.response_header['FLUTHER_TITLE'] if fluther.response_header['FLUTHER_TITLE']
|
84
|
+
request.env['fluther.header'] = fluther.response_header['FLUTHER_HEADER'] if fluther.response_header['FLUTHER_HEADER']
|
85
|
+
# @app.call request.env
|
86
|
+
true
|
87
|
+
end
|
88
|
+
result
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
metadata
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: simple-fluther
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 0.1.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Justin Chen
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-08-22 00:00:00 -07:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: em-http-request
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
version: "0"
|
33
|
+
type: :runtime
|
34
|
+
version_requirements: *id001
|
35
|
+
description: Modified version of original fluther gem for integrating into Rails.
|
36
|
+
email: justin@menuism.com
|
37
|
+
executables: []
|
38
|
+
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files:
|
42
|
+
- README.textile
|
43
|
+
files:
|
44
|
+
- MIT-LICENSE
|
45
|
+
- README.textile
|
46
|
+
- lib/simple-fluther.rb
|
47
|
+
- lib/simple-fluther/config.rb
|
48
|
+
- lib/simple-fluther/controller_methods.rb
|
49
|
+
has_rdoc: true
|
50
|
+
homepage: http://github.com/justinchen/simple-fluther
|
51
|
+
licenses: []
|
52
|
+
|
53
|
+
post_install_message:
|
54
|
+
rdoc_options:
|
55
|
+
- --charset=UTF-8
|
56
|
+
require_paths:
|
57
|
+
- lib
|
58
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
59
|
+
none: false
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
hash: 3
|
64
|
+
segments:
|
65
|
+
- 0
|
66
|
+
version: "0"
|
67
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
68
|
+
none: false
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
hash: 3
|
73
|
+
segments:
|
74
|
+
- 0
|
75
|
+
version: "0"
|
76
|
+
requirements: []
|
77
|
+
|
78
|
+
rubyforge_project:
|
79
|
+
rubygems_version: 1.3.7
|
80
|
+
signing_key:
|
81
|
+
specification_version: 3
|
82
|
+
summary: Ruby interface to the Fluther discussion system
|
83
|
+
test_files: []
|
84
|
+
|