imprenta 0.0.3 → 0.0.4
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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +6 -0
- data/README.md +55 -4
- data/Rakefile +11 -0
- data/imprenta.gemspec +5 -1
- data/lib/imprenta/cache_page.rb +8 -17
- data/lib/imprenta/configuration.rb +5 -0
- data/lib/imprenta/content_rack.rb +27 -0
- data/lib/imprenta/content_server/file.rb +36 -0
- data/lib/imprenta/content_server/s3.rb +32 -0
- data/lib/imprenta/rails.rb +5 -1
- data/lib/imprenta/static_server.rb +3 -7
- data/lib/imprenta/storage/S3.rb +39 -0
- data/lib/imprenta/storage/file.rb +25 -0
- data/lib/imprenta/version.rb +1 -1
- data/lib/imprenta.rb +7 -3
- data/spec/configuration_spec.rb +57 -0
- data/spec/dummy/README.rdoc +261 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +13 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/controllers/home_controller.rb +10 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/mailers/.gitkeep +0 -0
- data/spec/dummy/app/models/.gitkeep +0 -0
- data/spec/dummy/app/views/home/dummy.html.erb +1 -0
- data/spec/dummy/app/views/home/index.html.erb +1 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/config/application.rb +17 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +12 -0
- data/spec/dummy/config/environments/production.rb +12 -0
- data/spec/dummy/config/environments/test.rb +12 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +15 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +5 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/lib/assets/.gitkeep +0 -0
- data/spec/dummy/log/.gitkeep +0 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +25 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/features/publish_spec.rb +26 -0
- data/spec/file_storage_spec.rb +25 -0
- data/spec/spec_helper.rb +16 -0
- data/spec/support/dummy_rack.rb +5 -0
- metadata +152 -9
- data/lib/imprenta/file_rack.rb +0 -48
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a41c878c7744c585924be4102d5f1bd9a8139dfc
|
4
|
+
data.tar.gz: 1be6f4b0bbba656894081372eae2cd0b3e134806
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 27c87f0c08066a52c5367fe2d37d8f37bfc255d3d1cb006136d1a79677af5499a483263a1e0b67cd03acd591d78be702982c262d4b9d116621e5d5b0db2cd2bf
|
7
|
+
data.tar.gz: bbf9c4a5bfe0863f80b19905585900d4ccbe49694dce25ce288e35518f84b3e244e162860d4d81e4f592b28ae62675adb8b9977a48d486bb616681fc73b3d7b3
|
data/.gitignore
CHANGED
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -1,8 +1,11 @@
|
|
1
|
-
|
1
|
+
[](http://travis-ci.org/skyscrpr/imprenta)
|
2
|
+
[](https://codeclimate.com/repos/5272d3faf3ea004b9c013f64/feed)
|
3
|
+
|
4
|
+
# Imprenta - Publish and Serve Static Pages within Rails.
|
2
5
|
|
3
6
|
The goal of this gem is to provide an easy and efficient way to generate and serve
|
4
7
|
static pages within Rails. The perfect use case for this gem is when your users
|
5
|
-
generate some content that gets published and
|
8
|
+
generate some content that gets published and after this it almost never change. e.g: a blog post,
|
6
9
|
landing page, about.me, etc.
|
7
10
|
|
8
11
|
The gem will provide with methods to save generated templates as static html pages.
|
@@ -36,8 +39,6 @@ def publish
|
|
36
39
|
redirect_to root_path, success: 'Yei page published!'
|
37
40
|
end
|
38
41
|
```
|
39
|
-
|
40
|
-
|
41
42
|
|
42
43
|
Then in your routes add the following:
|
43
44
|
|
@@ -45,8 +46,16 @@ Then in your routes add the following:
|
|
45
46
|
get 'mystatic-pages/:id', :to => Imprenta.server
|
46
47
|
```
|
47
48
|
|
49
|
+
Now if you go to your server to following url:
|
50
|
+
```code
|
51
|
+
http://localhost:3000/mystatic-pages/mytemplateid
|
52
|
+
```
|
53
|
+
|
54
|
+
You should be able to see the page you cached in the publish action.
|
48
55
|
## Configuration
|
49
56
|
|
57
|
+
### Middlewares
|
58
|
+
|
50
59
|
Imprenta allows you to customize the Rack Server (Imprenta.server) with your own middlewares. By defaut, it
|
51
60
|
will have loaded a middleware to handle 500,400,401,404, etc.
|
52
61
|
|
@@ -56,6 +65,48 @@ Imprenta.configure do |config|
|
|
56
65
|
end
|
57
66
|
```
|
58
67
|
|
68
|
+
### Storage
|
69
|
+
|
70
|
+
Imprenta provides two kinds of storage to save the static pages: File and S3. The default one is file.
|
71
|
+
If you want to use s3. You can configure the gem the following way:
|
72
|
+
|
73
|
+
|
74
|
+
```ruby
|
75
|
+
Imprenta.configure do |config|
|
76
|
+
config.storage :s3
|
77
|
+
config.aws_bucket = "bucket"
|
78
|
+
config.aws_access_key_id = "xxxxid"
|
79
|
+
config.aws_secret_access_key = "xxxkey"
|
80
|
+
end
|
81
|
+
```
|
82
|
+
|
83
|
+
When using s3, it is strongly advisable to use it in conjunction with a reverse proxy (Varnish, Squid).
|
84
|
+
Otherwise, it will be hitting s3 for every request. In rails you could use rack-cache and memcached with
|
85
|
+
a configuration like this:
|
86
|
+
|
87
|
+
In your Gemfile:
|
88
|
+
|
89
|
+
```ruby
|
90
|
+
gem 'rack-cache'
|
91
|
+
gem 'dalli'
|
92
|
+
```
|
93
|
+
|
94
|
+
Then, in your initializer:
|
95
|
+
|
96
|
+
```ruby
|
97
|
+
Imprenta.configure do |config|
|
98
|
+
|
99
|
+
client = Dalli::Client.new('localhost:11211',
|
100
|
+
:value_max_bytes => 10485760)
|
101
|
+
|
102
|
+
config.middlewares.use Rack::Cache,
|
103
|
+
verbose: true,
|
104
|
+
metastore: client,
|
105
|
+
entitystore: client,
|
106
|
+
end
|
107
|
+
```
|
108
|
+
|
109
|
+
|
59
110
|
## Contributing
|
60
111
|
|
61
112
|
1. Fork it
|
data/Rakefile
CHANGED
@@ -1 +1,12 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
begin
|
3
|
+
require 'bundler/setup'
|
4
|
+
rescue LoadError
|
5
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
6
|
+
end
|
1
7
|
require "bundler/gem_tasks"
|
8
|
+
require 'rspec/core/rake_task'
|
9
|
+
RSpec::Core::RakeTask.new(:spec)
|
10
|
+
|
11
|
+
task :default => :spec
|
12
|
+
task :test => :spec
|
data/imprenta.gemspec
CHANGED
@@ -18,7 +18,11 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
+
spec.add_dependency "rails", "~> 4.0.0"
|
22
|
+
spec.add_dependency "fog"
|
21
23
|
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
-
spec.add_development_dependency "
|
24
|
+
spec.add_development_dependency "sqlite3"
|
25
|
+
spec.add_development_dependency "rspec-rails"
|
26
|
+
spec.add_development_dependency "capybara"
|
23
27
|
spec.add_development_dependency "rake"
|
24
28
|
end
|
data/lib/imprenta/cache_page.rb
CHANGED
@@ -1,32 +1,23 @@
|
|
1
1
|
module Imprenta
|
2
2
|
module CachePage
|
3
|
-
|
4
|
-
# https://github.com/rails/actionpack-page_caching
|
5
|
-
# We didn't need the whole gem. So I decided to get
|
6
|
-
# just what we need :)
|
3
|
+
|
7
4
|
def imprenta_cache_template(args = {})
|
8
5
|
template = args.fetch(:template)
|
9
6
|
layout = args.fetch(:layout) { 'application'}
|
10
7
|
id = args.fetch(:id)
|
11
8
|
|
12
9
|
content = render_to_string(template: template, layout: layout)
|
13
|
-
|
14
|
-
end
|
15
|
-
|
16
|
-
def imprenta_cache_page(content, id, extension = '.html', gzip = Zlib::BEST_COMPRESSION)
|
17
|
-
path = path_for_id(id, extension)
|
18
|
-
FileUtils.makedirs(File.dirname(path))
|
19
|
-
File.open(path, 'wb+') { |f| f.write(content) }
|
20
|
-
if gzip
|
21
|
-
Zlib::GzipWriter.open(path + '.gz', gzip) { |f| f.write(content) }
|
22
|
-
end
|
10
|
+
storage.persist(content, id)
|
23
11
|
end
|
24
12
|
|
25
13
|
private
|
26
14
|
|
27
|
-
def
|
28
|
-
|
29
|
-
|
15
|
+
def storage
|
16
|
+
@storage ||= case Imprenta.configuration.storage
|
17
|
+
when :file then Imprenta::Storage::File.new
|
18
|
+
when :s3 then Imprenta::Storage::S3.new
|
19
|
+
else raise StandardError.exception("Invalid storage provider")
|
20
|
+
end
|
30
21
|
end
|
31
22
|
end
|
32
23
|
end
|
@@ -3,7 +3,11 @@ module Imprenta
|
|
3
3
|
# Same configuration pattern that sferik uses in:
|
4
4
|
# https://github.com/sferik/mtgox/blob/master/lib/mtgox/configuration.rb
|
5
5
|
VALID_OPTIONS_KEYS = [:middlewares,
|
6
|
+
:storage,
|
6
7
|
:custom_domain,
|
8
|
+
:aws_access_key_id,
|
9
|
+
:aws_secret_access_key,
|
10
|
+
:aws_bucket,
|
7
11
|
:development]
|
8
12
|
|
9
13
|
attr_accessor *VALID_OPTIONS_KEYS
|
@@ -20,6 +24,7 @@ module Imprenta
|
|
20
24
|
def reset
|
21
25
|
self.middlewares = ActionDispatch::MiddlewareStack.new
|
22
26
|
self.development = false
|
27
|
+
self.storage = :file
|
23
28
|
self.custom_domain = false
|
24
29
|
end
|
25
30
|
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Imprenta
|
2
|
+
class ContentRack
|
3
|
+
attr_accessor :custom_domain, :content_server
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@custom_domain = Imprenta.configuration.custom_domain
|
7
|
+
@content_server = case Imprenta.configuration.storage
|
8
|
+
when :file then Imprenta::ContentServer::File.new
|
9
|
+
when :s3 then Imprenta::ContentServer::S3.new
|
10
|
+
else raise StandardError.exception("Invalid storage provider")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def call(env)
|
15
|
+
path = custom_domain ? env["SERVER_NAME"] : id_from_env(env)
|
16
|
+
raise ::ActionController::RoutingError.exception("Page Not Found") unless path
|
17
|
+
|
18
|
+
content_server.generate_response(path, env)
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def id_from_env(env)
|
24
|
+
env["action_dispatch.request.path_parameters"][:id]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Imprenta
|
2
|
+
module ContentServer
|
3
|
+
class File
|
4
|
+
def generate_response(path, env)
|
5
|
+
request = ::Rack::Request.new(env)
|
6
|
+
file, headers = pick_file_and_headers_for_path(path, request)
|
7
|
+
env.merge!("PATH_INFO" => "/")
|
8
|
+
::Rack::File.new(file, headers).call(env)
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def headers
|
14
|
+
@headers ||= {'Content-Type' => 'text/html' }
|
15
|
+
end
|
16
|
+
|
17
|
+
def pick_file_and_headers_for_path(path, request)
|
18
|
+
encoding = get_best_encoding(request)
|
19
|
+
file = "#{Rails.public_path}/imprenta/" + path + '.html'
|
20
|
+
if ::File.exist?(file)
|
21
|
+
if encoding == 'gzip'
|
22
|
+
file = file + '.gz'
|
23
|
+
headers['Content-Encoding'] = 'gzip'
|
24
|
+
end
|
25
|
+
else
|
26
|
+
raise ::ActionController::RoutingError.exception("Page Not Found")
|
27
|
+
end
|
28
|
+
[file, headers]
|
29
|
+
end
|
30
|
+
|
31
|
+
def get_best_encoding(request)
|
32
|
+
::Rack::Utils.select_best_encoding(%w(gzip identity), request.accept_encoding)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'open-uri'
|
2
|
+
module Imprenta
|
3
|
+
module ContentServer
|
4
|
+
class S3
|
5
|
+
|
6
|
+
attr_accessor :bucket
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@bucket = Imprenta.configuration.aws_bucket
|
10
|
+
end
|
11
|
+
|
12
|
+
def generate_response(path, env)
|
13
|
+
content = open("https://s3.amazonaws.com/#{bucket}/#{path}.html.gz")
|
14
|
+
if success?(content)
|
15
|
+
body = content.read
|
16
|
+
content.close
|
17
|
+
headers = content.meta.slice("etag", "last-modified", "content-type")
|
18
|
+
headers['Cache-Control'] = 'max-age=3600'
|
19
|
+
[200, headers, [body]]
|
20
|
+
else
|
21
|
+
raise ::ActionController::RoutingError.exception("Page Not Found")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def success?(content)
|
28
|
+
content.status[0] == "200"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/imprenta/rails.rb
CHANGED
@@ -1,11 +1,8 @@
|
|
1
1
|
module Imprenta
|
2
2
|
class StaticServer
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
def initialize(args = {})
|
7
|
-
@middleware_stack = args.fetch(:middlewares)
|
8
|
-
@custom_domain = args[:custom_domain]
|
4
|
+
def initialize
|
5
|
+
@middleware_stack = Imprenta.configuration.middlewares
|
9
6
|
end
|
10
7
|
|
11
8
|
def call(env)
|
@@ -16,8 +13,7 @@ module Imprenta
|
|
16
13
|
private
|
17
14
|
|
18
15
|
def build_app
|
19
|
-
@app ||= @middleware_stack.build(Imprenta::
|
16
|
+
@app ||= @middleware_stack.build(Imprenta::ContentRack.new)
|
20
17
|
end
|
21
|
-
|
22
18
|
end
|
23
19
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Imprenta
|
2
|
+
module Storage
|
3
|
+
class S3
|
4
|
+
|
5
|
+
attr_accessor :connection, :bucket
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@bucket = Imprenta.configuration.aws_bucket
|
9
|
+
@connection = Fog::Storage.new(provider: 'AWS',
|
10
|
+
aws_access_key_id: Imprenta.configuration.aws_access_key_id,
|
11
|
+
aws_secret_access_key: Imprenta.configuration.aws_secret_access_key)
|
12
|
+
end
|
13
|
+
|
14
|
+
def persist(content, id, extension = '.html', gzip = Zlib::BEST_COMPRESSION)
|
15
|
+
file_name = id + extension
|
16
|
+
write_body_to_s3(file_name, content)
|
17
|
+
if gzip
|
18
|
+
str = StringIO.new()
|
19
|
+
gz = Zlib::GzipWriter.new(str, gzip)
|
20
|
+
gz.write(content)
|
21
|
+
gz.close
|
22
|
+
write_body_to_s3(file_name + ".gz", str.string, 'gzip')
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def write_body_to_s3(key, body, encoding = nil)
|
27
|
+
directory.files.create(key: key,
|
28
|
+
body: body,
|
29
|
+
content_type: 'text/html',
|
30
|
+
content_encoding: encoding,
|
31
|
+
public: true)
|
32
|
+
end
|
33
|
+
|
34
|
+
def directory
|
35
|
+
@directory ||= connection.directories.create(key: bucket, public: true)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Imprenta
|
2
|
+
module Storage
|
3
|
+
class File
|
4
|
+
# This methods come from action_pack/cache_page'
|
5
|
+
# https://github.com/rails/actionpack-page_caching
|
6
|
+
# We didn't need the whole gem. So I decided to get
|
7
|
+
# just what we need :)
|
8
|
+
def persist(content, id, extension = '.html', gzip = Zlib::BEST_COMPRESSION)
|
9
|
+
path = path_for_id(id, extension)
|
10
|
+
FileUtils.makedirs(::File.dirname(path))
|
11
|
+
::File.open(path, 'wb+') { |f| f.write(content) }
|
12
|
+
if gzip
|
13
|
+
Zlib::GzipWriter.open(path + '.gz', gzip) { |f| f.write(content) }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def path_for_id(id, extension = nil)
|
20
|
+
page_cache_directory = Rails.public_path
|
21
|
+
page_cache_directory.to_s + '/imprenta/' + id + extension
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/imprenta/version.rb
CHANGED
data/lib/imprenta.rb
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
require "imprenta/version"
|
2
2
|
require "rails"
|
3
|
+
require "fog"
|
3
4
|
require "imprenta/configuration"
|
4
|
-
require "imprenta/
|
5
|
+
require "imprenta/storage/file"
|
6
|
+
require "imprenta/storage/S3"
|
5
7
|
require "imprenta/cache_page"
|
8
|
+
require "imprenta/content_server/file"
|
9
|
+
require "imprenta/content_server/s3"
|
10
|
+
require "imprenta/content_rack"
|
6
11
|
require "imprenta/static_server"
|
7
12
|
require "imprenta/rails"
|
8
13
|
|
@@ -10,8 +15,7 @@ module Imprenta
|
|
10
15
|
class << self
|
11
16
|
|
12
17
|
def server
|
13
|
-
Imprenta::StaticServer.new
|
14
|
-
custom_domain: configuration.custom_domain)
|
18
|
+
Imprenta::StaticServer.new
|
15
19
|
end
|
16
20
|
|
17
21
|
def configuration
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Imprenta configuraion" do
|
4
|
+
before do
|
5
|
+
Imprenta.configuration.reset
|
6
|
+
end
|
7
|
+
|
8
|
+
context "defaults" do
|
9
|
+
it "custom_domain is set to false" do
|
10
|
+
expect(Imprenta.configuration.custom_domain).to be_false
|
11
|
+
end
|
12
|
+
|
13
|
+
it "storage is set to false" do
|
14
|
+
expect(Imprenta.configuration.storage).to eq(:file)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "development is set to false" do
|
18
|
+
expect(Imprenta.configuration.development).to be_false
|
19
|
+
end
|
20
|
+
|
21
|
+
it "middlewares is initialized to a middleware stack" do
|
22
|
+
expect(Imprenta.configuration.middlewares).to be_kind_of(ActionDispatch::MiddlewareStack)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context "when configuring" do
|
27
|
+
context "fog" do
|
28
|
+
it "sets aws_secret_access_key " do
|
29
|
+
Imprenta.configure do |config|
|
30
|
+
config.aws_secret_access_key = "xxxsecret"
|
31
|
+
end
|
32
|
+
expect(Imprenta.configuration.aws_secret_access_key).to eq("xxxsecret")
|
33
|
+
end
|
34
|
+
|
35
|
+
it "aws_access_key_id" do
|
36
|
+
Imprenta.configure do |config|
|
37
|
+
config.aws_access_key_id = "xxxkeyid"
|
38
|
+
end
|
39
|
+
expect(Imprenta.configuration.aws_access_key_id).to eq("xxxkeyid")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
it "allows to set custom_domain to true" do
|
44
|
+
Imprenta.configure do |config|
|
45
|
+
config.custom_domain = true
|
46
|
+
end
|
47
|
+
expect(Imprenta.configuration.custom_domain).to be_true
|
48
|
+
end
|
49
|
+
|
50
|
+
it "allows to add custom racks to the config" do
|
51
|
+
Imprenta.configure do |config|
|
52
|
+
config.middlewares.use DummyRack
|
53
|
+
end
|
54
|
+
expect(Imprenta.configuration.middlewares.last).to eq(DummyRack)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|