remi-rack-staticifier 0.1.0
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.
- data/README.rdoc +25 -0
- data/Rakefile +68 -0
- data/VERSION.yml +4 -0
- data/lib/rack-staticifier.rb +57 -0
- data/lib/rack/staticifier.rb +2 -0
- data/spec/rack-staticifier_spec.rb +113 -0
- metadata +60 -0
data/README.rdoc
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
= Rack::Staticifier
|
2
|
+
|
3
|
+
Rack::Staticifier is Rack middleware for staticly caching responses.
|
4
|
+
|
5
|
+
There are lots of tools out there already for creating static sites, eg:
|
6
|
+
* Jekyll
|
7
|
+
* StaticMatic
|
8
|
+
* webgen
|
9
|
+
|
10
|
+
The problem with these tools, in my opinion, is that they make you code
|
11
|
+
your sites in a certain way.
|
12
|
+
|
13
|
+
What if you want to code your blog in Rails or Sinatra or something?
|
14
|
+
|
15
|
+
Rack::Staticifier is intended to solve this problem for you. If you want
|
16
|
+
to code your static site in any Rack-based web framework, go right ahead!
|
17
|
+
You can use Rack::Staticifier to statically cache responses to your app.
|
18
|
+
|
19
|
+
== Install
|
20
|
+
|
21
|
+
... coming soon ...
|
22
|
+
|
23
|
+
== Usage
|
24
|
+
|
25
|
+
... coming soon ...
|
data/Rakefile
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rubygems'
|
3
|
+
require 'rake/rdoctask'
|
4
|
+
require 'spec/rake/spectask'
|
5
|
+
|
6
|
+
puts "\nGem: rack-staticifier\n\n"
|
7
|
+
|
8
|
+
begin
|
9
|
+
require 'jeweler'
|
10
|
+
Jeweler::Tasks.new do |s|
|
11
|
+
s.name = 'rack-staticifier'
|
12
|
+
s.summary = ''
|
13
|
+
s.email = 'remi@remitaylor.com'
|
14
|
+
s.homepage = 'http://github.com/remi/rack-staticifier'
|
15
|
+
s.description = ''
|
16
|
+
s.authors = %w( remi )
|
17
|
+
s.files = FileList['[A-Z]*', '{lib,spec,bin,examples}/**/*']
|
18
|
+
# s.add_dependency 'person-gemname'
|
19
|
+
# s.executables << 'script'
|
20
|
+
# s.rubyforge_project = 'gemname'
|
21
|
+
# s.extra_rdoc_files = %w( README.rdoc )
|
22
|
+
end
|
23
|
+
rescue LoadError
|
24
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
25
|
+
end
|
26
|
+
|
27
|
+
Spec::Rake::SpecTask.new do |t|
|
28
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
29
|
+
end
|
30
|
+
|
31
|
+
desc "Run all examples with RCov"
|
32
|
+
Spec::Rake::SpecTask.new('rcov') do |t|
|
33
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
34
|
+
t.rcov = true
|
35
|
+
end
|
36
|
+
|
37
|
+
# require 'hanna'
|
38
|
+
# require 'darkfish-rdoc'
|
39
|
+
|
40
|
+
Rake::RDocTask.new do |rdoc|
|
41
|
+
rdoc.rdoc_dir = 'rdoc'
|
42
|
+
rdoc.title = 'rack-staticifier'
|
43
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
44
|
+
# rdoc.options += ["--template=#{`allison --path`}"] # sudo gem install allison
|
45
|
+
# rdoc.options += %w( -f darkfish ) # sudo gem install darkfish-rdoc
|
46
|
+
# rdoc.options += %w( -T hanna ) # sudo gem install mislav-hanna
|
47
|
+
rdoc.options += %w( -m README.rdoc ) # the initial page displayed
|
48
|
+
rdoc.rdoc_files.include('README.rdoc')
|
49
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
50
|
+
end
|
51
|
+
|
52
|
+
desc 'Confirm that gemspec is $SAFE'
|
53
|
+
task :safe do
|
54
|
+
require 'yaml'
|
55
|
+
require 'rubygems/specification'
|
56
|
+
data = File.read('rack-staticifier.gemspec')
|
57
|
+
spec = nil
|
58
|
+
if data !~ %r{!ruby/object:Gem::Specification}
|
59
|
+
Thread.new { spec = eval("$SAFE = 3\n#{data}") }.join
|
60
|
+
else
|
61
|
+
spec = YAML.load(data)
|
62
|
+
end
|
63
|
+
spec.validate
|
64
|
+
puts spec
|
65
|
+
puts "OK"
|
66
|
+
end
|
67
|
+
|
68
|
+
task :default => :spec
|
data/VERSION.yml
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
module Rack #:nodoc:
|
2
|
+
|
3
|
+
# Rack::Staticifier doco ...
|
4
|
+
class Staticifier
|
5
|
+
|
6
|
+
# the Rack application
|
7
|
+
attr_reader :app
|
8
|
+
|
9
|
+
# configuration options
|
10
|
+
attr_reader :config
|
11
|
+
|
12
|
+
def initialize app, config_options = nil, &block
|
13
|
+
@app = app
|
14
|
+
@config = default_config_options
|
15
|
+
|
16
|
+
config.merge!(config_options) if config_options
|
17
|
+
config[:cache_if] = block if block
|
18
|
+
end
|
19
|
+
|
20
|
+
def call env
|
21
|
+
response = @app.call env
|
22
|
+
cache_response(env, response) if should_cache_response?(env, response)
|
23
|
+
response
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def default_config_options
|
29
|
+
{ :root => 'cache' }
|
30
|
+
end
|
31
|
+
|
32
|
+
def should_cache_response? env, response
|
33
|
+
return true unless config.keys.include?(:cache_if) and config[:cache_if].respond_to?(:call)
|
34
|
+
should_cache = config[:cache_if].call(env, response)
|
35
|
+
should_cache
|
36
|
+
end
|
37
|
+
|
38
|
+
def cache_response env, response
|
39
|
+
request_path = env['PATH_INFO']
|
40
|
+
|
41
|
+
basename = ::File.basename request_path
|
42
|
+
dirname = ::File.join config[:root], ::File.dirname(request_path) # TODO grab 'public' from the config options
|
43
|
+
fullpath = ::File.join dirname, basename
|
44
|
+
|
45
|
+
FileUtils.mkdir_p(dirname)
|
46
|
+
::File.open(fullpath, 'w'){|f| f << response_body(response) }
|
47
|
+
end
|
48
|
+
|
49
|
+
def response_body response
|
50
|
+
body = ''
|
51
|
+
response.last.each {|string| body << string } # per the Rack spec, the last object should respond to #each
|
52
|
+
body
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rackbox'
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
require File.dirname(__FILE__) + '/../lib/rack-staticifier'
|
6
|
+
|
7
|
+
describe Rack::Staticifier do
|
8
|
+
|
9
|
+
before do
|
10
|
+
%w( public cache foo ).each {|dir| FileUtils.rm_rf dir }
|
11
|
+
@app = lambda {|env| [200, {}, ["hello from #{env['PATH_INFO']}"]] }
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'should cache all requests by default (in cache directory)' do
|
15
|
+
app = Rack::Staticifier.new @app
|
16
|
+
|
17
|
+
%w( foo bar ).each do |uri|
|
18
|
+
File.file?("cache/#{uri}.html").should be_false
|
19
|
+
RackBox.request app, "/#{uri}.html"
|
20
|
+
File.file?("cache/#{uri}.html").should be_true
|
21
|
+
File.read("cache/#{uri}.html").should == "hello from /#{uri}.html"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should cache all requests in a custom directory' do
|
26
|
+
app = Rack::Staticifier.new @app, :root => 'foo'
|
27
|
+
|
28
|
+
%w( foo bar ).each do |uri|
|
29
|
+
File.file?("foo/#{uri}.html").should be_false
|
30
|
+
RackBox.request app, "/#{uri}.html"
|
31
|
+
File.file?("foo/#{uri}.html").should be_true
|
32
|
+
File.read("foo/#{uri}.html").should == "hello from /#{uri}.html"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should cache all requests in a custom subdirectory' do
|
37
|
+
app = Rack::Staticifier.new @app, :root => 'foo/bar'
|
38
|
+
|
39
|
+
%w( foo bar ).each do |uri|
|
40
|
+
File.file?("foo/bar/#{uri}.html").should be_false
|
41
|
+
RackBox.request app, "/#{uri}.html"
|
42
|
+
File.file?("foo/bar/#{uri}.html").should be_true
|
43
|
+
File.read("foo/bar/#{uri}.html").should == "hello from /#{uri}.html"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should cache requests with slashes in them (create subdirectories)' do
|
48
|
+
app = Rack::Staticifier.new @app, :root => 'foo'
|
49
|
+
|
50
|
+
%w( hi/there a/b/c/1/2/3 totally/neato ).each do |uri|
|
51
|
+
File.file?("foo/#{uri}.html").should be_false
|
52
|
+
RackBox.request app, "/#{uri}.html"
|
53
|
+
File.file?("foo/#{uri}.html").should be_true
|
54
|
+
File.read("foo/#{uri}.html").should == "hello from /#{uri}.html"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'should be able to only cache requests based on request environment' do
|
59
|
+
app = Rack::Staticifier.new @app, :cache_if => lambda {|env,resp| env['PATH_INFO'].include?('cache') }
|
60
|
+
|
61
|
+
%w( hi there crazy/person ).each do |uri|
|
62
|
+
File.file?("cache/#{uri}.html").should be_false
|
63
|
+
RackBox.request app, "/#{uri}.html"
|
64
|
+
File.file?("cache/#{uri}.html").should be_false
|
65
|
+
end
|
66
|
+
|
67
|
+
%w( cache cache-me please/cache/me ).each do |uri|
|
68
|
+
File.file?("cache/#{uri}.html").should be_false
|
69
|
+
RackBox.request app, "/#{uri}.html"
|
70
|
+
File.file?("cache/#{uri}.html").should be_true
|
71
|
+
File.read("cache/#{uri}.html").should == "hello from /#{uri}.html"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'should be able to only cache requests based on request environment (by passing a block)' do
|
76
|
+
app = Rack::Staticifier.new(@app){ |env,resp| env['PATH_INFO'].include?('cache') }
|
77
|
+
|
78
|
+
%w( hi there crazy/person ).each do |uri|
|
79
|
+
File.file?("cache/#{uri}.html").should be_false
|
80
|
+
RackBox.request app, "/#{uri}.html"
|
81
|
+
File.file?("cache/#{uri}.html").should be_false
|
82
|
+
end
|
83
|
+
|
84
|
+
%w( cache cache-me please/cache/me ).each do |uri|
|
85
|
+
File.file?("cache/#{uri}.html").should be_false
|
86
|
+
RackBox.request app, "/#{uri}.html"
|
87
|
+
File.file?("cache/#{uri}.html").should be_true
|
88
|
+
File.read("cache/#{uri}.html").should == "hello from /#{uri}.html"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'should be able to only cache requests based on generated response' do
|
93
|
+
app = Rack::Staticifier.new @app, :cache_if => lambda {|env,resp|
|
94
|
+
body = ''
|
95
|
+
resp[2].each {|s| body << s }
|
96
|
+
body.include?("hello from /foo")
|
97
|
+
}
|
98
|
+
|
99
|
+
%w( nope hi not/start/with/foo/x nor-me-foo ).each do |uri|
|
100
|
+
File.file?("cache/#{uri}.html").should be_false
|
101
|
+
RackBox.request app, "/#{uri}.html"
|
102
|
+
File.file?("cache/#{uri}.html").should be_false
|
103
|
+
end
|
104
|
+
|
105
|
+
%w( foo fooooo foo/bar ).each do |uri|
|
106
|
+
File.file?("cache/#{uri}.html").should be_false
|
107
|
+
RackBox.request app, "/#{uri}.html"
|
108
|
+
File.file?("cache/#{uri}.html").should be_true
|
109
|
+
File.read("cache/#{uri}.html").should == "hello from /#{uri}.html"
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
metadata
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: remi-rack-staticifier
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- remi
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-05-06 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: ""
|
17
|
+
email: remi@remitaylor.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files: []
|
23
|
+
|
24
|
+
files:
|
25
|
+
- Rakefile
|
26
|
+
- VERSION.yml
|
27
|
+
- README.rdoc
|
28
|
+
- lib/rack-staticifier.rb
|
29
|
+
- lib/rack
|
30
|
+
- lib/rack/staticifier.rb
|
31
|
+
- spec/rack-staticifier_spec.rb
|
32
|
+
has_rdoc: true
|
33
|
+
homepage: http://github.com/remi/rack-staticifier
|
34
|
+
post_install_message:
|
35
|
+
rdoc_options:
|
36
|
+
- --inline-source
|
37
|
+
- --charset=UTF-8
|
38
|
+
require_paths:
|
39
|
+
- lib
|
40
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: "0"
|
45
|
+
version:
|
46
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: "0"
|
51
|
+
version:
|
52
|
+
requirements: []
|
53
|
+
|
54
|
+
rubyforge_project:
|
55
|
+
rubygems_version: 1.2.0
|
56
|
+
signing_key:
|
57
|
+
specification_version: 2
|
58
|
+
summary: ""
|
59
|
+
test_files: []
|
60
|
+
|