├── lib
├── thumbor_rails
│ ├── version.rb
│ └── helpers.rb
├── generators
│ └── thumbor_rails
│ │ ├── templates
│ │ └── config
│ │ │ └── initializers
│ │ │ └── thumbor_rails.rb
│ │ └── install_generator.rb
└── thumbor_rails.rb
├── Gemfile
├── spec
├── spec_helper.rb
├── thumbor_rails_spec.rb
└── thumbor_rails
│ └── helpers_spec.rb
├── gemfiles
├── rails_4.2.gemfile
├── rails_5.1.gemfile
└── rails_5.0.gemfile
├── Appraisals
├── Rakefile
├── .editorconfig
├── .travis.yml
├── .gitignore
├── LICENSE
├── thumbor_rails.gemspec
└── README.md
/lib/thumbor_rails/version.rb:
--------------------------------------------------------------------------------
1 | module ThumborRails
2 | VERSION = '1.2.0'
3 | end
4 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | gem 'rails', '>= 4.0'
4 |
5 | gemspec
6 |
--------------------------------------------------------------------------------
/spec/spec_helper.rb:
--------------------------------------------------------------------------------
1 | $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2 | require 'action_view'
3 | require 'thumbor_rails'
4 |
--------------------------------------------------------------------------------
/gemfiles/rails_4.2.gemfile:
--------------------------------------------------------------------------------
1 | # This file was generated by Appraisal
2 |
3 | source "https://rubygems.org"
4 |
5 | gem "rails", "~> 4.2.0"
6 |
7 | gemspec path: "../"
8 |
--------------------------------------------------------------------------------
/gemfiles/rails_5.1.gemfile:
--------------------------------------------------------------------------------
1 | # This file was generated by Appraisal
2 |
3 | source "https://rubygems.org"
4 |
5 | gem "rails", ">= 5.1", "< 5.2"
6 |
7 | gemspec path: "../"
8 |
--------------------------------------------------------------------------------
/gemfiles/rails_5.0.gemfile:
--------------------------------------------------------------------------------
1 | # This file was generated by Appraisal
2 |
3 | source "https://rubygems.org"
4 |
5 | gem "rails", ">= 5.0.0.alpha", "< 5.1"
6 |
7 | gemspec path: "../"
8 |
--------------------------------------------------------------------------------
/lib/generators/thumbor_rails/templates/config/initializers/thumbor_rails.rb:
--------------------------------------------------------------------------------
1 | ThumborRails.setup do |config|
2 | config.server_url = 'http://thumbor.example.com'
3 | config.security_key = 'MY_SECURITY_KEY'
4 | end
5 |
--------------------------------------------------------------------------------
/Appraisals:
--------------------------------------------------------------------------------
1 | appraise 'rails-4.2' do
2 | gem 'rails', '~> 4.2.0'
3 | end
4 |
5 | appraise 'rails-5.0' do
6 | gem 'rails', '>= 5.0.0.alpha', '< 5.1'
7 | end
8 |
9 | appraise 'rails-5.1' do
10 | gem 'rails', '>= 5.1', '< 5.2'
11 | end
12 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | require 'rubygems'
2 | require 'bundler/setup'
3 | require 'bundler/gem_tasks'
4 | require 'rspec/core/rake_task'
5 |
6 | desc 'Default: run specs.'
7 | task :default => :spec
8 |
9 | desc 'Run all specs'
10 | RSpec::Core::RakeTask.new(:spec)
11 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 |
3 | root = true
4 |
5 | # Unix-style newlines with a newline ending every file
6 | [*]
7 | indent_style = space
8 | indent_size = 2
9 | end_of_line = lf
10 | charset = utf-8
11 | trim_trailing_whitespace = true
12 | insert_final_newline = true
13 |
14 | [*.markdown]
15 | trim_trailing_whitespace = false
16 |
--------------------------------------------------------------------------------
/lib/thumbor_rails.rb:
--------------------------------------------------------------------------------
1 | require 'thumbor_rails/helpers'
2 |
3 | module ThumborRails
4 | mattr_accessor :server_url
5 | @@server_url = 'http://thumbor.example.com'
6 |
7 | mattr_accessor :security_key
8 | @@security_key = nil
9 |
10 | mattr_accessor :force_no_protocol_in_source_url
11 | @@force_no_protocol_in_source_url = false
12 |
13 | def self.setup
14 | yield self
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/lib/generators/thumbor_rails/install_generator.rb:
--------------------------------------------------------------------------------
1 | module ThumborRails
2 | module Generators
3 | class InstallGenerator < Rails::Generators::Base
4 | desc "Copy ThumborRails default configuration files"
5 | source_root File.expand_path('../templates', __FILE__)
6 |
7 | def copy_config
8 | template "config/initializers/thumbor_rails.rb"
9 | end
10 | end
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: ruby
2 | rvm:
3 | - 2.4.1
4 | - 2.3.4
5 | - 2.2.7
6 | cache: bundler
7 | sudo: false
8 | gemfile:
9 | - gemfiles/rails_4.2.gemfile
10 | - gemfiles/rails_5.0.gemfile
11 | - gemfiles/rails_5.1.gemfile
12 | script: bundle exec rake
13 | matrix:
14 | fast_finish: true
15 | exclude:
16 | - gemfile: gemfiles/rails_5.0.gemfile
17 | rvm: 2.2
18 | - gemfile: gemfiles/rails_5.1.gemfile
19 | rvm: 2.2
20 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.rbc
2 | capybara-*.html
3 | .rspec
4 | /log
5 | /tmp
6 | /db/*.sqlite3
7 | /public/system
8 | /coverage/
9 | /spec/tmp
10 | **.orig
11 | rerun.txt
12 | pickle-email-*.html
13 | config/initializers/secret_token.rb
14 | config/secrets.yml
15 |
16 | ## Environment normalisation:
17 | /.bundle
18 | /vendor/bundle
19 |
20 | # these should all be checked in to normalise the environment:
21 | # Gemfile.lock, .ruby-version, .ruby-gemset
22 |
23 | # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
24 | .rvmrc
25 | *.gem
26 | Gemfile.lock
27 | *.gemfile.lock
28 | gemfiles/.bundle/
29 |
--------------------------------------------------------------------------------
/spec/thumbor_rails_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe ThumborRails do
4 | it 'setup block yields self' do
5 | subject.setup do |config|
6 | expect(subject).to equal(config)
7 | end
8 | end
9 |
10 | it 'has security_key attibute' do
11 | expect(subject).to respond_to 'security_key'
12 | end
13 |
14 | it 'has server_url attibute' do
15 | expect(subject).to respond_to 'server_url'
16 | end
17 |
18 | it 'has force_no_protocol_in_source_url attibute' do
19 | expect(subject).to respond_to 'force_no_protocol_in_source_url'
20 | end
21 |
22 | describe 'when configured' do
23 | before do
24 | subject.setup do |config|
25 | config.server_url = 'http://thumbor.example.com'
26 | end
27 | end
28 |
29 | it 'should use the configuration' do
30 | expect(subject.server_url).to eq('http://thumbor.example.com')
31 | end
32 | end
33 | end
34 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Rafael Carício
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/thumbor_rails.gemspec:
--------------------------------------------------------------------------------
1 | # -*- encoding: utf-8 -*-
2 | lib = File.expand_path('../lib/', __FILE__)
3 | $:.unshift lib unless $:.include?(lib)
4 | require 'thumbor_rails/version'
5 |
6 | Gem::Specification.new do |s|
7 | s.name = "thumbor_rails"
8 | s.version = ThumborRails::VERSION
9 |
10 | s.authors = ["Rafael Caricio"]
11 | s.description = "thumbor_rails is a client for the thumbor imaging service (http://github.com/globocom/thumbor) for Ruby and Rails projects."
12 | s.email = ["rafael@caricio.com"]
13 | s.files = Dir.glob('lib/**/*.rb') << 'README.md'
14 | s.test_files = Dir.glob('spec/**/*.rb')
15 | s.homepage = "https://github.com/rafaelcaricio/thumbor_rails"
16 | s.rdoc_options = ["--main", "README.md"]
17 | s.summary = "thumbor_rails is a client to manage and generate urls for the thumbor imaging service (http://github.com/globocom/thumbor) for Ruby and Rails projects."
18 | s.license = "MIT"
19 |
20 | s.add_dependency 'ruby-thumbor', '>= 1.2.1'
21 |
22 | s.add_runtime_dependency 'rails', '>= 4.0'
23 |
24 | s.add_development_dependency 'rspec'
25 | s.add_development_dependency 'rake'
26 | s.add_development_dependency 'appraisal'
27 | end
28 |
--------------------------------------------------------------------------------
/lib/thumbor_rails/helpers.rb:
--------------------------------------------------------------------------------
1 | require 'ruby-thumbor'
2 |
3 | module ThumborRails
4 | module Helpers
5 | include ActionView::Helpers::AssetTagHelper
6 |
7 | def thumbor_url(image_url, options = {})
8 | if ThumborRails.force_no_protocol_in_source_url
9 | image_url = image_url.sub(/^http(s|):\/\//, '')
10 | end
11 |
12 | unless options[:unsafe]
13 | image_url = ERB::Util.url_encode(image_url)
14 | end
15 |
16 | options[:image] = image_url
17 | thumbor_service = crypto_service
18 | thumbor_service = unsafe_service if options[:unsafe]
19 | host = ThumborRails.server_url
20 | path = thumbor_service.generate(options)
21 | if host =~ /%d/
22 | host = host % (Zlib.crc32(path) % 4)
23 | end
24 | ENV.has_key?("DISABLE_THUMBOR") ? CGI::unescape(image_url) : (host + path)
25 | end
26 |
27 | def thumbor_image_tag(image_url, options = {}, tag_attrs = {})
28 | tag_attrs[:alt] ||= image_alt(image_url)
29 | image_tag(thumbor_url(image_url, options), tag_attrs)
30 | end
31 |
32 | private
33 |
34 | def crypto_service
35 | Thumbor::CryptoURL.new(ThumborRails.security_key)
36 | end
37 |
38 | def unsafe_service
39 | Thumbor::CryptoURL.new(nil)
40 | end
41 | end
42 | end
43 |
44 | ActionView::Base.send :include, ThumborRails::Helpers
45 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Thumbor Rails [
](https://travis-ci.org/rafaelcaricio/thumbor_rails)
2 |
3 | https://github.com/rafaelcaricio/thumbor_rails
4 |
5 | ## DESCRIPTION
6 |
7 | thumbor_rails is a client to make easier to use the thumbor imaging service (http://github.com/globocom/thumbor) in Ruby and Rails projects.
8 |
9 | ## Installation
10 |
11 | You can use this gem by putting the following inside your Gemfile:
12 |
13 | ```
14 | gem "thumbor_rails", "1.2.0"
15 | ```
16 |
17 | Now generate the thumbor basic client configuration:
18 |
19 | ```
20 | rails g thumbor_rails:install
21 | ```
22 |
23 | It will generate the basic configuration in `config/initializers/thumbor_rails.rb`, which has the following configuration options available:
24 |
25 | - `server_url`. _Required_. The location of your Thumbor server. If `server_url` contains `%d`, it will be interpolated to 0-3, [just like `asset_host` for Rails](http://api.rubyonrails.org/classes/ActionView/Helpers/AssetUrlHelper.html).
26 | - `sercurity_key`. Optional. This must match your [Thumbor server's security key](https://github.com/thumbor/thumbor/wiki/Security#stopping-tampering).
27 | - `force_no_protocol_in_source_url`. Optional, defaults to `false`. If true, the protocol is removed from any image source passed into `thumbor_url`. This may be done for aesthetic reasons, or due to certain CDN/server configurations.
28 |
29 |
30 | ## Usage
31 |
32 | There are two basic helpers you can use in your views:
33 |
34 | ```
35 | thumbor_url
36 | thumbor_image_tag
37 | ```
38 |
39 | ### thumbor_url
40 |
41 | The `thumbor_url` helper allows you to to generate a thumbor url, a simple use is:
42 |
43 | ```ruby
44 | <%= thumbor_url "http://example.com/awesome_image.jpg" %>
45 | ```
46 |
47 | Of course, you can pass various parameters to thumbor as described in the [ruby-thumbor gem](https://github.com/thumbor/ruby-thumbor#usage). An exemple would be:
48 |
49 | ```ruby
50 | <%= thumbor_url "http://example.com/awesome_image.jpg", width: 200, height: 300 %>
51 | ```
52 |
53 | ### thumbor_image_tag
54 |
55 | The `thumbor_image_tag` helper allows you to simplify the usage when creating a simple image tag in your views. It returns a complete image tag with the generated thumbor url in the `src` attribute of the `img` tag. Example:
56 |
57 | ```ruby
58 | <%= thumbor_image_tag "http://myimage.jpg", unsafe: true, width: 100, height: 100 %>
59 | ```
60 |
61 | Will result in something like:
62 |
63 | ```html
64 |
65 | ```
66 |
67 | ### Disabling Thumbor
68 |
69 | Setting the `DISABLE_THUMBOR` environment variable will disable `thumbor_image_tag` and `thumbor_url` and they will return the original url instead. This is in case you don't want to use Thumbor locally or want to disable it temporarily.
70 |
71 | ## Maintainers
72 |
73 | - Rafael Caricio ([@rafaelcaricio](https://coderwall.com/rafaelcaricio))
74 |
75 | and [contributors](https://github.com/rafaelcaricio/thumbor_rails/graphs/contributors).
76 |
77 | ## Contributing
78 |
79 | 1. Fork it
80 | 2. Create your feature branch (`git checkout -b my-new-feature`)
81 | 3. Commit your changes (`git commit -am 'Add some feature'`)
82 | 4. Push to the branch (`git push origin my-new-feature`)
83 | 5. Create new Pull Request
84 |
85 | ## Extras
86 |
87 | If you do not have yet an instance of thumbor for you. You can get one for [free up and running](https://github.com/rafaelcaricio/thumbor-openshift-example) in the OpenShift Cloud.
88 |
--------------------------------------------------------------------------------
/spec/thumbor_rails/helpers_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe ThumborRails::Helpers do
4 | let(:params) { { } }
5 | let(:options) { { } }
6 |
7 |
8 | include ThumborRails::Helpers
9 |
10 | before do
11 | ThumborRails.setup do |config|
12 | config.security_key = 'MY_SECURITY_KEY'
13 | end
14 | end
15 |
16 | describe 'encoding image url for generation valid Security Token' do
17 | subject { thumbor_url('http://test.img', params) }
18 |
19 | context 'enabled' do
20 | it {
21 | should include('http%3A%2F%2Ftest.img')
22 | }
23 | end
24 |
25 | context 'disabled when unsafe enabled' do
26 | let(:params) { { unsafe: true } }
27 | it {
28 | should include('http://test.img')
29 | }
30 | end
31 | end
32 |
33 | describe 'interpolate thumbor hosts with %d to 0-3, like Rails asset_host' do
34 | subject { thumbor_url('http://test.img') }
35 | let!(:original_url) { ThumborRails.server_url }
36 | before { ThumborRails.server_url = server_url }
37 | after { ThumborRails.server_url = original_url }
38 |
39 | context 'when url is set to "http://thumbor%d.com"' do
40 | let(:server_url) { 'http://thumbor%d.com' }
41 | it { should eq('http://thumbor0.com/su8uxlZzewqybJYZUPALFtZBrhE=/http%3A%2F%2Ftest.img') }
42 | end
43 | end
44 |
45 | describe 'automatically remove the protocol in source urls' do
46 | subject { thumbor_url("#{protocol}test.img", unsafe: true) }
47 | before { ThumborRails.force_no_protocol_in_source_url = true }
48 | after { ThumborRails.force_no_protocol_in_source_url = false }
49 |
50 | context 'when http' do
51 | let(:protocol) { 'http://' }
52 | it { should eq "http://thumbor.example.com/unsafe/test.img" }
53 | end
54 |
55 | context 'when https' do
56 | let(:protocol) { 'https://' }
57 | it { should eq "http://thumbor.example.com/unsafe/test.img" }
58 | end
59 |
60 | context 'when no protocol' do
61 | let(:protocol) { 'www.' }
62 | it { should eq "http://thumbor.example.com/unsafe/www.test.img" }
63 | end
64 | end
65 |
66 | describe '#thumbor_url' do
67 | subject { thumbor_url('http://test.img', params) }
68 |
69 | context 'basic encrypted url' do
70 | it { should eq('http://thumbor.example.com/su8uxlZzewqybJYZUPALFtZBrhE=/http%3A%2F%2Ftest.img') }
71 | end
72 |
73 | context 'allow unsafe urls' do
74 | let(:params) { { unsafe: true } }
75 | it { should eq('http://thumbor.example.com/unsafe/http://test.img') }
76 | end
77 |
78 | context 'pass arguments to thumbor' do
79 | let(:params) { { unsafe: true, width: 100, height: 200 } }
80 | it { should eq('http://thumbor.example.com/unsafe/100x200/http://test.img') }
81 | end
82 | end
83 |
84 | describe '#thumbor_image_tag' do
85 | subject { thumbor_image_tag('http://myimg.jpg', params, options) }
86 |
87 | context 'unsafe disabled' do
88 | it {
89 | should include('src="http://thumbor.example.com/yWSvmN9j2QTZlzKTsmBhOWgYvEw=/http%3A%2F%2Fmyimg.jpg"')
90 | should include('alt="Myimg"')
91 | }
92 | end
93 |
94 | context 'unsafe enabled' do
95 | let(:params) { { unsafe: true } }
96 | it {
97 | should include('src="http://thumbor.example.com/unsafe/http://myimg.jpg"')
98 | should include('alt="Myimg"')
99 | }
100 | end
101 |
102 | context 'alt options сhangeable and valid' do
103 | let(:options) { { alt: 'Yourimg' } }
104 | it {
105 | should include('alt="Yourimg"')
106 | }
107 | end
108 | end
109 |
110 | describe 'ENV["DISABLE_THUMBOR"]' do
111 | subject { thumbor_url('http://test.img', params) }
112 |
113 | context 'when set' do
114 | before { ENV["DISABLE_THUMBOR"] = 'true' }
115 | it { should eq('http://test.img') }
116 | end
117 |
118 | context 'when not set' do
119 | before { ENV.delete("DISABLE_THUMBOR") }
120 | it { should eq('http://thumbor.example.com/su8uxlZzewqybJYZUPALFtZBrhE=/http%3A%2F%2Ftest.img') }
121 | end
122 | end
123 | end
124 |
--------------------------------------------------------------------------------