turnout 0.3.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4208ab9f575833c1136e95f562967f73c0d447ff
4
- data.tar.gz: abac3c012ceb68cab13c4f743cc4ba99dd781340
3
+ metadata.gz: 41d171143907e5993b28b8c17d1e45605ec22fbb
4
+ data.tar.gz: fc4f2847372f888e391d8afb282c4ad125d7534f
5
5
  SHA512:
6
- metadata.gz: db27f6aa29b51d5821f9ae79edb5aecc9be8e428c6684d791f65e47424e2342b7a826ae5bc4bd991ba2692f9a0df2e0adc775cce5c097e874568a1ca83dbf189
7
- data.tar.gz: 3285dd2df5fcefd131e1bde7ed4cef9f4c4f489380b25bd59b7c70fb8c6df5496dc3a078d832496bda6fe812131aec06e9fbad5c0feaeb9fdc596caba2fdb836
6
+ metadata.gz: 668f8abb73f83a5581f621e212783561a3334ced28a4348e4780de4c8025bcb190224bf6eca58c9aa3001f64e0264ad71c5e4945452e0c90fd7ea8eda76389a9
7
+ data.tar.gz: 4d962edd21460ec6814a46ff9d59bea226a54d146d8084fbb04d26f87145ec0354255d7675305bbd5a6c70fdf373497534769abbd477c0e73855f25c39f47572
data/README.markdown CHANGED
@@ -1,6 +1,6 @@
1
- Turnout [![Build Status](https://travis-ci.org/biola/turnout.png?branch=master)](https://travis-ci.org/biola/turnout)
1
+ Turnout [![Build Status](https://travis-ci.org/biola/turnout.png?branch=master)](https://travis-ci.org/biola/turnout) [![Code Climate](https://codeclimate.com/github/biola/turnout.png)](https://codeclimate.com/github/biola/turnout)
2
2
  =======
3
- Turnout is a [Ruby on Rails](http://rubyonrails.org) engine with a [Rack](http://rack.rubyforge.org/) component that allows you to put your Rails app in maintenance mode.
3
+ Turnout is [Rack](http://rack.rubyforge.org/) middleware with a [Ruby on Rails](http://rubyonrails.org) engine that allows you to easily put your app in maintenance mode.
4
4
 
5
5
  Features
6
6
  ========
@@ -11,11 +11,12 @@ Features
11
11
  * Allow certain paths to be accessible during maintenance
12
12
  * Easily override the default maintenance.html file with your own
13
13
  * Simple [YAML](http://yaml.org) based config file for easy activation, deactivation and configuration without the rake commands
14
- * Supports Rails 2.3 - 3.0 and Ruby 1.8.7 - 1.9.3
14
+ * SUpport for multiple maintenance page formats. Current [HTML](http://en.wikipedia.org/wiki/HTML) and [JSON](http://en.wikipedia.org/wiki/JSON)
15
+ * Supports Rails, [Sinatra](http://sinatrarb.com) and any other Rack application
15
16
 
16
17
  Installation
17
18
  ============
18
- Rails 3
19
+ Rails 3+
19
20
  -------
20
21
  In your `Gemfile` add:
21
22
 
@@ -25,20 +26,6 @@ then run
25
26
 
26
27
  bundle install
27
28
 
28
- Rails 2.3
29
- ---------
30
- In your `config/environment.rb` file add:
31
-
32
- config.gem 'turnout'
33
-
34
- then run
35
-
36
- rake gems:install
37
-
38
- then in your `Rakefile` add:
39
-
40
- require 'turnout/rake_tasks'
41
-
42
29
 
43
30
  Activation
44
31
  ==========
@@ -74,10 +61,54 @@ Deactivation
74
61
 
75
62
  rake maintenance:end
76
63
 
64
+ Configuration
65
+ =============
66
+
67
+ Turnout can be configured in two different ways:
68
+
69
+ 1. __Pass a config hash to the middleware__
70
+
71
+ ```ruby
72
+ use Rack::Turnout,
73
+ app_root: '/some/path',
74
+ named_maintenance_file_paths: {app: 'tmp/app.yml', server: '/tmp/server.yml'},
75
+ default_mainteance_page: Turnout::MaintenancePage::JSON,
76
+ default_reason: 'Somebody googled Google!',
77
+ default_response_code: 418
78
+ ```
79
+
80
+ 2. __Using a config block__
81
+
82
+ ```ruby
83
+ Turonut.configure do |config|
84
+ config.app_root = '/some/path'
85
+ config.named_maintenance_file_paths = {app: 'tmp/app.yml', server: '/tmp/server.yml'},
86
+ config.default_maintenance_page = Turnout::MaintenancePage::JSON
87
+ config.default_reason = 'Somebody googled Google!'
88
+ config.default_response_code = 418
89
+ end
90
+ ```
91
+
92
+ __NOTICE:__ Any custom configuration should be loaded not only in the app but in the rake task. This should happen automatically in Rails as the `environment` task is run if it exists. But you may want to create your own `environment` task in non-Rails apps.
93
+
94
+ Default Configuration
95
+ ---------------------
96
+
97
+ ```ruby
98
+ Turnout.configure do |config|
99
+ config.app_root = '.',
100
+ config.named_maintenance_file_paths = {default: app_root.join('tmp', 'maintenance.yml').to_s},
101
+ config.default_maintenance_page = Turnout::MaintenancePage::HTML,
102
+ config.default_reason = "The site is temporarily down for maintenance.\nPlease check back soon.",
103
+ config.default_response_code = 503
104
+ end
105
+ }
106
+ ```
107
+
77
108
  Customization
78
109
  =============
79
110
 
80
- A [default maintenance page](https://github.com/biola/turnout/blob/master/public/maintenance.html) is provided, but you can create your own `public/maintenance.html` instead. If you provide a `reason` to the rake task, Turnout will use [Nokogiri](http://nokogiri.org) to parse the `maintenance.html` file and attempt to find a tag with `id="reason"`. It will replace the `inner_html` of the tag with the reason you provided. So be sure your `maintenance.html` file can be parsed as HTML.
111
+ [Default maintenance pages](https://github.com/biola/turnout/blob/master/public/) are provided, but you can create your own `public/maintenance.[html|json]` files instead. If you provide a `reason` to the rake task, Turnout will parse the maintenance page file and attempt to replace a [Liquid](http://liquidmarkup.org/)-style `{{ reason }}` tag with the provided reason. So be sure to include a `{{ reason }}` tag in your `maintenance.html` file.
81
112
 
82
113
  Tips
83
114
  ====
@@ -88,22 +119,27 @@ However you can achieve the same sort of functionality by using
88
119
 
89
120
  rake maintenance:start allowed_paths="^(?!/your/under/maintenance/path)"
90
121
 
122
+ A central `named_maintenance_file_path` can be configured in all your apps such as `/tmp/turnout.yml` so that all apps on a server can be put into mainteance mode at once. You could even configure service based paths such as `/tmp/mongodb_maintenance.yml` so that all apps using MongoDB could be put into maintenance mode.
123
+
91
124
  Behind the Scenes
92
125
  =================
93
126
  On every request the Rack app will check to see if `tmp/maintenance.yml` exists. If the file exists the maintenance page will be shown (unless allowed IPs are given and the requester is in the allowed range).
94
127
 
95
- So if you want to get the maintenance page up or down in a hury `touch tmp/maintenance.yml` and `rm tmp/maintenance.yml` will work.
128
+ So if you want to get the maintenance page up or down in a hurry `touch tmp/maintenance.yml` and `rm tmp/maintenance.yml` will work.
96
129
 
97
- Turnout will attempt to parse the `maintenance.yml` file looking for `reason` and `allowed_ip` settings. The file is not cached so you can change these values manually or just rerun the `rake maintenance:start` command.
130
+ Turnout will attempt to parse the `maintenance.yml` file looking for `reason`, `allowed_ip` and other settings. The file is checked on every request so you can change these values manually or just rerun the `rake maintenance:start` command.
98
131
 
99
132
  Example maintenance.yml File
100
133
  ----------------------------
101
134
 
102
- ---
103
- reason: Someone told me I should type <code>sudo rm -rf /</code>
104
- allowed_paths:
105
- - ^/help
106
- - ^/contact_us
107
- allowed_ips:
108
- - 127.0.0.1
109
- - 192.168.0.0/24
135
+ ```yaml
136
+ ---
137
+ reason: Someone told me I should type <code>sudo rm -rf /</code>
138
+ allowed_paths:
139
+ - ^/help
140
+ - ^/contact_us
141
+ allowed_ips:
142
+ - 127.0.0.1
143
+ - 192.168.0.0/24
144
+ response_code: 503
145
+ ```
data/lib/rack/turnout.rb CHANGED
@@ -1,111 +1,28 @@
1
1
  require 'rack'
2
- require 'yaml'
3
- require 'ipaddr'
4
- require 'nokogiri'
2
+ require 'turnout'
5
3
 
6
4
  class Rack::Turnout
7
5
  def initialize(app, config={})
8
6
  @app = app
9
- @config = config
10
- end
11
7
 
12
- def call(env)
13
- self.request = Rack::Request.new(env)
14
- reload_settings
8
+ Turnout.config.update config
15
9
 
16
- if on?
17
- [ response_code, { 'Content-Type' => 'text/html', 'Content-Length' => content_length }, [content] ]
18
- else
19
- @app.call(env)
10
+ if config[:app_root].nil? && app.respond_to?(:app_root)
11
+ Turnout.config.app_root = app.app_root
20
12
  end
21
13
  end
22
14
 
23
- protected
24
-
25
- attr_accessor :request
26
-
27
- def on?
28
- maintenance_file_exists? && !request_allowed?
29
- end
30
-
31
- def request_allowed?
32
- path_allowed? || ip_allowed?
33
- end
34
-
35
- def path_allowed?
36
- (settings['allowed_paths'] || []).any? do |allowed_path|
37
- request.path =~ Regexp.new(allowed_path)
38
- end
39
- end
40
-
41
- def ip_allowed?
42
- begin
43
- ip = IPAddr.new(request.ip.to_s)
44
- rescue ArgumentError
45
- return false
46
- end
47
-
48
- (settings['allowed_ips'] || []).any? do |allowed_ip|
49
- IPAddr.new(allowed_ip).include? ip
50
- end
51
- end
15
+ def call(env)
16
+ request = Turnout::Request.new(env)
17
+ settings = Turnout::MaintenanceFile.find
52
18
 
53
- def reload_settings
54
- @settings = nil
55
- settings
56
- end
19
+ if settings && !request.allowed?(settings)
20
+ page_class = Turnout::MaintenancePage.best_for(env)
21
+ page = page_class.new(settings.reason)
57
22
 
58
- def settings
59
- @settings ||= if File.exists? settings_file
60
- YAML::load(File.open(settings_file)) || {}
23
+ page.rack_response(settings.response_code)
61
24
  else
62
- {}
63
- end
64
- end
65
-
66
- def app_root
67
- @app_root ||= Pathname.new(
68
- @config[:app_root] || @app.respond_to?(:root)? @app.root.to_s : '.'
69
- )
70
- end
71
-
72
- def settings_file
73
- app_root.join('tmp', 'maintenance.yml')
74
- end
75
-
76
- def maintenance_file_exists?
77
- File.exists? settings_file
78
- end
79
-
80
- def maintenance_page
81
- File.exists?(app_maintenance_page) ? app_maintenance_page : default_maintenance_page
82
- end
83
-
84
- def app_maintenance_page
85
- @app_maintenance_page ||= app_root.join('public', 'maintenance.html')
86
- end
87
-
88
- def default_maintenance_page
89
- @default_maintenance_page ||= File.expand_path('../../../public/maintenance.html', __FILE__)
90
- end
91
-
92
- def content_length
93
- content.size.to_s
94
- end
95
-
96
- def content
97
- content = File.open(maintenance_page, 'rb').read
98
-
99
- if settings['reason']
100
- html = Nokogiri::HTML(content)
101
- html.at_css('#reason').inner_html = Nokogiri::HTML.fragment(settings['reason'])
102
- content = html.to_s
25
+ @app.call(env)
103
26
  end
104
-
105
- content
106
- end
107
-
108
- def response_code
109
- settings['response_code'] || 503
110
27
  end
111
28
  end
@@ -1,45 +1,48 @@
1
+ require 'turnout'
2
+
1
3
  namespace :maintenance do
2
- desc 'Enable the maintenance mode page ("reason", "allowed_paths" and "allowed_ips" can be passed as environment variables)'
3
- task :start do |t, args|
4
- settings = {
5
- 'reason' => ENV['reason'],
6
- 'allowed_paths' => split_paths(ENV['allowed_paths']),
7
- 'allowed_ips' => split_ips(ENV['allowed_ips']),
8
- 'response_code' => ENV['response_code']
9
- }
10
-
11
- file = File.open settings_file, 'w'
12
- file.write settings.to_yaml
13
- file.close
14
-
15
- puts "Created #{settings_file}"
16
- puts "Run `rake maintenance:end` to stop maintenance mode"
4
+ desc 'Enable the maintenance mode page ("reason", "allowed_paths", "allowed_ips" and "response_code" can be passed as environment variables)'
5
+ rule /\Amaintenance:(.*:|)start\Z/ do |task|
6
+ invoke_environment
7
+
8
+ maint_file = maintenance_file_for(task)
9
+ maint_file.import_env_vars(ENV)
10
+ maint_file.write
11
+
12
+ puts "Created #{maint_file.path}"
13
+ puts "Run `rake #{task.name.gsub(/\:start/, ':end')}` to stop maintenance mode"
17
14
  end
18
15
 
19
16
  desc 'Disable the maintenance mode page'
20
- task :end do
21
- File.delete settings_file
17
+ rule /\Amaintenance:(.*:|)end\Z/ do |task|
18
+ invoke_environment
19
+
20
+ maint_file = maintenance_file_for(task)
22
21
 
23
- puts "Deleted #{settings_file}"
22
+ if maint_file.delete
23
+ puts "Deleted #{maint_file.path}"
24
+ else
25
+ fail 'Could not find a maintenance file to delete'
26
+ end
24
27
  end
25
28
 
26
- def settings_file
27
- Rails.root.join('tmp', 'maintenance.yml')
29
+ def invoke_environment
30
+ if Rake::Task.task_defined? 'environment'
31
+ Rake::Task['environment'].invoke
32
+ end
28
33
  end
29
34
 
30
- def split_paths(paths_string)
31
- # I had this for 1.9.2 but no lookbehinds in 1.8.7 :(
32
- #paths = paths_string.to_s.split(/(?<!\\),\ ?/)
35
+ def maintenance_file_for(task)
36
+ path_name = (task.name.split(':') - ['maintenance', 'start', 'end']).join(':')
33
37
 
34
- # Grab everything between commas that aren't escaped with a backslash
35
- paths = paths_string.to_s.scan(/(?:\\,|[^,])+/)
36
- paths.map! do |path|
37
- path.strip.gsub('\,', ',') # remove the escape characters
38
+ maint_file = if path_name == ''
39
+ Turnout::MaintenanceFile.default
40
+ else
41
+ Turnout::MaintenanceFile.named(path_name)
38
42
  end
39
- paths
40
- end
41
43
 
42
- def split_ips(ips_string)
43
- ips_string.to_s.split(',')
44
+ fail %{Unknown path name: "#{path_name}"} if maint_file.nil?
45
+
46
+ maint_file
44
47
  end
45
48
  end
@@ -0,0 +1,36 @@
1
+ module Turnout
2
+ class Configuration
3
+ SETTINGS = [:app_root, :named_maintenance_file_paths, :default_maintenance_page, :default_reason, :default_response_code]
4
+
5
+ SETTINGS.each do |setting|
6
+ attr_accessor setting
7
+ end
8
+
9
+ def initialize
10
+ @app_root = '.'
11
+ @named_maintenance_file_paths = {default: app_root.join('tmp', 'maintenance.yml').to_s}
12
+ @default_maintenance_page = Turnout::MaintenancePage::HTML
13
+ @default_reason = "The site is temporarily down for maintenance.\nPlease check back soon."
14
+ @default_response_code = 503
15
+ end
16
+
17
+ def app_root
18
+ Pathname.new(@app_root.to_s)
19
+ end
20
+
21
+ def named_maintenance_file_paths=(named_paths)
22
+ # Force keys to symbols
23
+ @named_maintenance_file_paths = Hash[named_paths.map { |k, v| [k.to_sym, v] }]
24
+ end
25
+
26
+ def update(settings_hash)
27
+ settings_hash.each do |setting, value|
28
+ unless SETTINGS.include? setting.to_sym
29
+ raise ArgumentError, "invalid setting: #{setting}"
30
+ end
31
+
32
+ self.public_send "#{setting}=", value
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,114 @@
1
+ require 'yaml'
2
+ require 'fileutils'
3
+
4
+ module Turnout
5
+ class MaintenanceFile
6
+ attr_reader :path
7
+
8
+ SETTINGS = [:reason, :allowed_paths, :allowed_ips, :response_code]
9
+ attr_reader *SETTINGS
10
+
11
+ def initialize(path)
12
+ @path = path
13
+ @reason = Turnout.config.default_reason
14
+ @allowed_paths = []
15
+ @allowed_ips = []
16
+ @response_code = Turnout.config.default_response_code
17
+
18
+ import_yaml if exists?
19
+ end
20
+
21
+ def exists?
22
+ File.exists? path
23
+ end
24
+
25
+ def to_h
26
+ SETTINGS.each_with_object({}) do |att, hash|
27
+ hash[att] = send(att)
28
+ end
29
+ end
30
+
31
+ def to_yaml(key_mapper = :to_s)
32
+ to_h.each_with_object({}) { |(key, val), hash|
33
+ hash[key.send(key_mapper)] = val
34
+ }.to_yaml
35
+ end
36
+
37
+ def write
38
+ FileUtils.mkdir_p(dir_path) unless Dir.exists? dir_path
39
+
40
+ File.open(path, 'w') do |file|
41
+ file.write to_yaml
42
+ end
43
+ end
44
+
45
+ def delete
46
+ File.delete(path) if exists?
47
+ end
48
+
49
+ def import(hash)
50
+ SETTINGS.map(&:to_s).each do |att|
51
+ self.send(:"#{att}=", hash[att]) unless hash[att].nil?
52
+ end
53
+
54
+ true
55
+ end
56
+ alias :import_env_vars :import
57
+
58
+ # Find the first MaintenanceFile that exists
59
+ def self.find
60
+ path = named_paths.values.find { |path| File.exists? path }
61
+ self.new(path) if path
62
+ end
63
+
64
+ def self.named(name)
65
+ path = named_paths[name.to_sym]
66
+ self.new(path) unless path.nil?
67
+ end
68
+
69
+ def self.default
70
+ self.new(named_paths.values.first)
71
+ end
72
+
73
+ private
74
+
75
+ def reason=(reason)
76
+ @reason = reason.to_s
77
+ end
78
+
79
+ # Splits strings on commas for easier importing of environment variables
80
+ def allowed_paths=(paths)
81
+ if paths.is_a? String
82
+ # Grab everything between commas that aren't escaped with a backslash
83
+ paths = paths.to_s.split(/(?<!\\),\ ?/).map do |path|
84
+ path.strip.gsub('\,', ',') # remove the escape characters
85
+ end
86
+ end
87
+
88
+ @allowed_paths = paths
89
+ end
90
+
91
+ # Splits strings on commas for easier importing of environment variables
92
+ def allowed_ips=(ips)
93
+ ips = ips.to_s.split(',') if ips.is_a? String
94
+
95
+ @allowed_ips = ips
96
+ end
97
+
98
+ def response_code=(code)
99
+ @response_code = code.to_i
100
+ end
101
+
102
+ def dir_path
103
+ File.dirname(path)
104
+ end
105
+
106
+ def import_yaml
107
+ import YAML::load(File.open(path)) || {}
108
+ end
109
+
110
+ def self.named_paths
111
+ Turnout.config.named_maintenance_file_paths
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,73 @@
1
+ module Turnout
2
+ module MaintenancePage
3
+ class Base
4
+ attr_reader :reason
5
+
6
+ def initialize(reason = nil)
7
+ @reason = reason
8
+ end
9
+
10
+ def rack_response(code = Turnout.config.default_response_code)
11
+ [code, headers, body]
12
+ end
13
+
14
+ # Override with an array of media type strings. i.e. text/html
15
+ def self.media_types
16
+ raise NotImplementedError, '.media_types must be overridden in subclasses'
17
+ end
18
+ def media_types() self.class.media_types end
19
+
20
+ # Override with a file extension value like 'html' or 'json'
21
+ def self.extension
22
+ raise NotImplementedError, '.extension must be overridden in subclasses'
23
+ end
24
+ def extension() self.class.extension end
25
+
26
+ protected
27
+
28
+ def self.inherited(subclass)
29
+ MaintenancePage.all << subclass
30
+ end
31
+
32
+ def headers
33
+ {'Content-Type' => media_types.first, 'Content-Length' => length}
34
+ end
35
+
36
+ def length
37
+ content.size.to_s
38
+ end
39
+
40
+ def body
41
+ [content]
42
+ end
43
+
44
+ def content
45
+ file_content.gsub /{{\s?reason\s?}}/, reason
46
+ end
47
+
48
+ def file_content
49
+ File.read(path)
50
+ end
51
+
52
+ def path
53
+ if File.exists? custom_path
54
+ custom_path
55
+ else
56
+ default_path
57
+ end
58
+ end
59
+
60
+ def default_path
61
+ File.expand_path("../../../../public/#{filename}", __FILE__)
62
+ end
63
+
64
+ def custom_path
65
+ Turnout.config.app_root.join('public', filename)
66
+ end
67
+
68
+ def filename
69
+ "maintenance.#{extension}"
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,20 @@
1
+ module Turnout
2
+ module MaintenancePage
3
+ class HTML < Base
4
+ def reason
5
+ super.to_s.split("\n").map{|txt| "<p>#{txt}</p>" }.join("\n")
6
+ end
7
+
8
+ def self.media_types
9
+ %w{
10
+ text/html
11
+ application/xhtml+xml
12
+ }
13
+ end
14
+
15
+ def self.extension
16
+ 'html'
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,26 @@
1
+ require 'json'
2
+
3
+ module Turnout
4
+ module MaintenancePage
5
+ class JSON < Base
6
+ def reason
7
+ super.to_s.to_json
8
+ end
9
+
10
+ def self.media_types
11
+ %w{
12
+ application/json
13
+ text/json
14
+ application/x-javascript
15
+ text/javascript
16
+ text/x-javascript
17
+ text/x-json
18
+ }
19
+ end
20
+
21
+ def self.extension
22
+ 'json'
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,24 @@
1
+ module Turnout
2
+ module MaintenancePage
3
+ require 'rack/accept'
4
+
5
+ def self.all
6
+ @all ||= []
7
+ end
8
+
9
+ def self.best_for(env)
10
+ request = Rack::Accept::Request.new(env)
11
+
12
+ all_types = all.map(&:media_types).flatten
13
+ best_type = request.best_media_type(all_types)
14
+
15
+ best = all.find { |page| page.media_types.include? best_type }
16
+
17
+ best || Turnout.default_maintenance_page
18
+ end
19
+
20
+ require 'turnout/maintenance_page/base'
21
+ require 'turnout/maintenance_page/html'
22
+ require 'turnout/maintenance_page/json'
23
+ end
24
+ end
@@ -0,0 +1,35 @@
1
+ require 'ipaddr'
2
+
3
+ module Turnout
4
+ class Request
5
+ def initialize(env)
6
+ @rack_request = Rack::Request.new(env)
7
+ end
8
+
9
+ def allowed?(settings)
10
+ path_allowed?(settings.allowed_paths) || ip_allowed?(settings.allowed_ips)
11
+ end
12
+
13
+ private
14
+
15
+ attr_reader :rack_request
16
+
17
+ def path_allowed?(allowed_paths)
18
+ allowed_paths.any? do |allowed_path|
19
+ rack_request.path =~ Regexp.new(allowed_path)
20
+ end
21
+ end
22
+
23
+ def ip_allowed?(allowed_ips)
24
+ begin
25
+ ip = IPAddr.new(rack_request.ip.to_s)
26
+ rescue ArgumentError
27
+ return false
28
+ end
29
+
30
+ allowed_ips.any? do |allowed_ip|
31
+ IPAddr.new(allowed_ip).include? ip
32
+ end
33
+ end
34
+ end
35
+ end
@@ -1,3 +1,3 @@
1
1
  module Turnout
2
- VERSION = '0.3.0'
2
+ VERSION = '1.0.0'
3
3
  end
data/lib/turnout.rb CHANGED
@@ -1,3 +1,15 @@
1
1
  module Turnout
2
+ require 'turnout/configuration'
3
+ require 'turnout/maintenance_file'
4
+ require 'turnout/maintenance_page'
5
+ require 'turnout/request'
2
6
  require 'turnout/engine' if defined? Rails
7
+
8
+ def self.configure
9
+ yield config
10
+ end
11
+
12
+ def self.config
13
+ @config ||= Configuration.new
14
+ end
3
15
  end
@@ -58,9 +58,8 @@
58
58
  </header>
59
59
 
60
60
  <section id="body">
61
- <div id="reason">
62
- <p>The site is temporarily down for maintenance.</p>
63
- <p>Please check back soon.</p>
61
+ <div>
62
+ {{ reason }}
64
63
  </div>
65
64
  </section>
66
65
 
@@ -0,0 +1 @@
1
+ {"error":"Service Unavailable","message":{{ reason }}}
metadata CHANGED
@@ -1,43 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: turnout
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Crownoble
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-08 00:00:00.000000000 Z
11
+ date: 2014-06-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: nokogiri
14
+ name: rack
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '1.3'
19
+ version: '0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '1.3'
26
+ version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: rack
28
+ name: rack-accept
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: '0.4'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: '0.4'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rack-test
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -78,10 +78,18 @@ files:
78
78
  - lib/rack/turnout.rb
79
79
  - lib/tasks/maintenance.rake
80
80
  - lib/turnout.rb
81
+ - lib/turnout/configuration.rb
81
82
  - lib/turnout/engine.rb
83
+ - lib/turnout/maintenance_file.rb
84
+ - lib/turnout/maintenance_page.rb
85
+ - lib/turnout/maintenance_page/base.rb
86
+ - lib/turnout/maintenance_page/html.rb
87
+ - lib/turnout/maintenance_page/json.rb
82
88
  - lib/turnout/rake_tasks.rb
89
+ - lib/turnout/request.rb
83
90
  - lib/turnout/version.rb
84
91
  - public/maintenance.html
92
+ - public/maintenance.json
85
93
  - rails/init.rb
86
94
  homepage: https://github.com/biola/turnout
87
95
  licenses:
@@ -108,3 +116,4 @@ signing_key:
108
116
  specification_version: 4
109
117
  summary: A Rack based maintenance mode plugin for Rails
110
118
  test_files: []
119
+ has_rdoc: