Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

plugin 機構で config.ru を操作 #315

Merged
merged 15 commits into from
Jun 5, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ end
# use edge tDiary contrib
# gem 'tdiary-contrib', :git => 'git@github.com:tdiary/tdiary-contrib.git'

gem 'sprockets'
gem 'coffee-script', :group => [:development, :test]

gem 'omniauth'
Expand Down
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ PATH
rack (>= 1.0.0)
rake (>= 10.0.0)
rdtool (>= 0.6.0)
sprockets (~> 2.10)
thor (~> 0.18)

GEM
Expand Down Expand Up @@ -177,7 +178,6 @@ DEPENDENCIES
selenium-webdriver
sequel
simplecov
sprockets
sqlite3
tapp
tdiary!
Expand Down
67 changes: 5 additions & 62 deletions config.ru
Original file line number Diff line number Diff line change
@@ -1,64 +1,7 @@
$:.unshift( File::dirname( __FILE__ ).untaint )
require 'tdiary/environment'
require 'tdiary/application'

require 'tdiary'
require 'tdiary/rack/html_anchor'
require 'tdiary/rack/valid_request_path'
require 'tdiary/rack/auth/basic'
require 'omniauth'
require 'tdiary/rack/auth/omniauth'

use Rack::Reloader unless ENV['RACK_ENV'] == 'production'

base_dir = ''

# OmniAuth settings
use Rack::Session::Pool, :expire_after => 2592000
use OmniAuth::Builder do
configure {|conf| conf.path_prefix = "#{base_dir}/auth" }
# provider :twitter, ENV['TWITTER_KEY'], ENV['TWITTER_SECRET']
# provider :github, ENV['GITHUB_KEY'], ENV['GITHUB_SECRET']
end
map "#{base_dir}/auth" do
run TDiary::Rack::Auth::OmniAuth::CallbackHandler.new
end

map "#{base_dir}/update.rb" do
# Basic Auth
use TDiary::Rack::Auth::Basic, '.htpasswd'

# OAuth
# use TDiary::Rack::Auth::OmniAuth, :twitter do |auth|
# auth.info.nickname == 'your_twitter_screen_name'
# end

run TDiary::Application.new(:update)
end

map "#{base_dir}/assets" do
environment = Sprockets::Environment.new
%w(js theme).each {|path| environment.append_path File.join(TDiary.root, path) }

# FIXME: dirty hack, it should create TDiary::Server::Config.assets_path
TDiary::Contrib::Assets.setup(environment) if defined?(TDiary::Contrib)

# if you need to auto compilation for CoffeeScript
# require 'tdiary/rack/assets/precompile'
# use TDiary::Rack::Assets::Precompile, environment

run environment
end

map "#{base_dir}/" do
use TDiary::Rack::HtmlAnchor
run Rack::Cascade.new([
Rack::File.new("./public/"),
TDiary::Rack::ValidRequestPath.new(TDiary::Application.new(:index))
])
end

# Local Variables:
# mode: ruby
# indent-tabs-mode: t
# tab-width: 3
# ruby-indent-level: 3
# End:
use ::Rack::Reloader unless ENV['RACK_ENV'] == 'production'
base_dir = '/'
run TDiary::Application.new( base_dir )
10 changes: 7 additions & 3 deletions spec/acceptance_helper.rb
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
require 'spec_helper'
require 'sprockets'

Dir["#{File.dirname(__FILE__)}/acceptance/support/**/*.rb"].each {|f| require f}

Capybara.app = Rack::Builder.new do
map '/' do
run TDiary::Application.new(:index)
run TDiary::Dispatcher.index
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

これは cool ですねえ

end

map '/index.rb' do
run TDiary::Application.new(:index)
run TDiary::Dispatcher.index
end

map '/update.rb' do
run TDiary::Application.new(:update)
run TDiary::Dispatcher.update
end
end

# FIXME: TDiary::Application has auth middleware in update.rb, so it cannot be tested.
# Capybara.app = TDiary::Application.new

Capybara.save_and_open_page_path = File.dirname(__FILE__) + '/../tmp/capybara'

RSpec.configure do |config|
Expand Down
22 changes: 22 additions & 0 deletions spec/core/rack/static_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
require 'spec_helper'
require 'rack/test'
require 'tdiary/rack/static'

describe TDiary::Rack::Static do
include Rack::Test::Methods

describe "reserve static files" do
let(:app) { TDiary::Rack::Static.new(
lambda{|env| [500, {}, ['Internal Server Error']]}, 'doc')}

it 'should return the file in static directory' do
get '/README.md'
last_response.should be_ok
end

it 'should run the app if file is not exist' do
get '/index.rb'
last_response.status.should be 500
end
end
end
2 changes: 2 additions & 0 deletions tdiary.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ Gem::Specification.new do |spec|
spec.add_dependency 'rdtool', '>= 0.6.0'
spec.add_dependency 'imagesize', '>= 0.1.0'

spec.add_dependency 'sprockets', '~> 2.10'

spec.add_dependency 'thor', '~> 0.18'
spec.add_dependency "bundler", "~> 1.3"
end
87 changes: 53 additions & 34 deletions tdiary/application.rb
Original file line number Diff line number Diff line change
@@ -1,51 +1,70 @@
# -*- coding: utf-8 -*-

# FIXME too dirty hack :-<
class CGI
def env_table_rack
$RACK_ENV
end

alias :env_table_orig :env_table
alias :env_table :env_table_rack
end
require 'rack/builder'
require 'tdiary/application/configuration'
require 'tdiary/rack'
require 'sprockets'

module TDiary
class Application
def initialize( target )
@target = target
class << self
def configure(&block)
instance_eval &block
end

def config
@config ||= Configuration.new
end
end

def initialize( base_dir = '/' )
@app = ::Rack::Builder.app {
map base_dir do
Application.config.builder_procs.each do |builder_proc|
instance_eval &builder_proc
end
end
}
end

def call( env )
req = adopt_rack_request_to_plain_old_tdiary_style( env )
dispatch_request( req )
@app.call( env )
end
end

private
Application.configure do
config.assets_paths.concat %w(js theme).map {|path|
File.join(TDiary.root, path)
}

def adopt_rack_request_to_plain_old_tdiary_style( env )
req = TDiary::Request.new( env )
req.params # fill params to tdiary_request
$RACK_ENV = req.env
env["rack.input"].rewind
fake_stdin_as_params
req
end
config.builder do
map Application.config.path[:index] do
use TDiary::Rack::HtmlAnchor
use TDiary::Rack::Static, "public"
use TDiary::Rack::ValidRequestPath
run TDiary::Dispatcher.index
end

def dispatch_request( request )
dispatcher = TDiary::Dispatcher.__send__( @target )
dispatcher.dispatch_cgi( request )
end
map Application.config.path[:update] do
instance_eval &Application.config.authenticate_proc
run TDiary::Dispatcher.update
end

map Application.config.path[:assets] do
environment = Sprockets::Environment.new
Application.config.assets_paths.each do |path|
environment.append_path path
end

def fake_stdin_as_params
stdin_spy = StringIO.new( "" )
# FIXME dirty hack
if $RACK_ENV && $RACK_ENV['rack.input']
stdin_spy.print( $RACK_ENV['rack.input'].read )
stdin_spy.rewind
if Application.config.assets_precompile
require 'tdiary/rack/assets/precompile'
use TDiary::Rack::Assets::Precompile, environment
end

run environment
end
$stdin = stdin_spy
end

config.authenticate TDiary::Rack::Auth::Basic, '.htpasswd'
end
end

Expand Down
36 changes: 36 additions & 0 deletions tdiary/application/configuration.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
module TDiary
class Application
class Configuration
attr_accessor :assets_paths, :assets_precompile, :plugin_paths, :path, :builder_procs, :authenticate_proc

def initialize
@assets_paths = []
# if you need to auto compilation for CoffeeScript
@assets_precompile = false;
@plugin_paths = []
@path = {
index: '/',
update: '/update.rb',
assets: '/assets'
}
@builder_procs = []
@authenticate_proc = proc { }
end

def builder(&block)
@builder_procs << block
end

def authenticate(middleware, *params, &block)
@authenticate_proc = proc { use middleware, *params, &block }
end
end
end
end

# Local Variables:
# mode: ruby
# indent-tabs-mode: t
# tab-width: 3
# ruby-indent-level: 3
# End:
23 changes: 23 additions & 0 deletions tdiary/application/extensions/omniauth.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
require 'tdiary/application'
require 'tdiary/rack/auth/omniauth'

TDiary::Application.configure do
config.builder do
use ::Rack::Session::Pool, :expire_after => 2592000
use OmniAuth::Builder do
configure {|conf| conf.path_prefix = "/auth" }
provider :twitter, ENV['TWITTER_KEY'], ENV['TWITTER_SECRET']
provider :github, ENV['GITHUB_KEY'], ENV['GITHUB_SECRET']
end

map('/auth') do
run TDiary::Rack::Auth::OmniAuth::CallbackHandler.new
end
end

config.authenticate TDiary::Rack::Auth::OmniAuth, :twitter do |auth|
# TODO: an user can setting
auth.info.nickname == 'your_twitter_screen_name'
end
end
36 changes: 36 additions & 0 deletions tdiary/dispatcher.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
# -*- coding: utf-8; -*-
require 'stringio'

# FIXME too dirty hack :-<
class CGI
def env_table_rack
$RACK_ENV
end

alias :env_table_orig :env_table
alias :env_table :env_table_rack
end

module TDiary
class Dispatcher

Expand All @@ -16,6 +26,11 @@ def initialize( target )
@target = TARGET[target]
end

def call( env )
req = adopt_rack_request_to_plain_old_tdiary_style( env )
dispatch_cgi( req )
end

# FIXME rename method name to more suitable one.
def dispatch_cgi( request, cgi = CGI.new )
result = @target.run( request, cgi )
Expand Down Expand Up @@ -66,6 +81,27 @@ def update
end
private :new
end

private

def adopt_rack_request_to_plain_old_tdiary_style( env )
req = TDiary::Request.new( env )
req.params # fill params to tdiary_request
$RACK_ENV = req.env
env["rack.input"].rewind
fake_stdin_as_params
req
end

def fake_stdin_as_params
stdin_spy = StringIO.new( "" )
# FIXME dirty hack
if $RACK_ENV && $RACK_ENV['rack.input']
stdin_spy.print( $RACK_ENV['rack.input'].read )
stdin_spy.rewind
end
$stdin = stdin_spy
end
end
end

Expand Down
Loading