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 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,4 @@
1
+ ---
2
+ :patch: 0
3
+ :major: 0
4
+ :minor: 1
@@ -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,2 @@
1
+ # require 'rack/staticifier'
2
+ require 'rack-staticifier'
@@ -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
+