├── 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 [Build Status](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 | Myimage 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 | --------------------------------------------------------------------------------