diff --git a/.env.example b/.env.example index 7bc7367..7e032da 100644 --- a/.env.example +++ b/.env.example @@ -1,3 +1,7 @@ export AWS_KEY={value} export AWS_SECRET={value} export AWS_BUCKET={value} + +export CLOUDINARY_CLOUD_NAME={value} +export CLOUDINARY_API_KEY={value} +export CLOUDINARY_API_SECRET={value} diff --git a/Gemfile b/Gemfile index 1939ce3..7398ce1 100644 --- a/Gemfile +++ b/Gemfile @@ -53,6 +53,7 @@ group :production do end gem 'administrate' +gem 'cloudinary', github: 'cloudinary/cloudinary_gem' gem 'dragonfly' gem 'dragonfly-s3_data_store' gem 'exception_notification', :git => 'git://github.com/rails/exception_notification', :require => 'exception_notifier' diff --git a/Gemfile.lock b/Gemfile.lock index e856e32..4f388b8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,3 +1,11 @@ +GIT + remote: git://github.com/cloudinary/cloudinary_gem.git + revision: 5ebbb4ee2cb23d59c39e889a27577782c9f013d3 + specs: + cloudinary (1.1.0) + aws_cf_signer + rest-client + GIT remote: git://github.com/rails/exception_notification revision: 192a49a02d63d28b23ed41cebadfedd490929cf1 @@ -67,6 +75,7 @@ GEM jmespath (~> 1.0) aws-sdk-resources (2.1.29) aws-sdk-core (= 2.1.29) + aws_cf_signer (0.1.3) bcrypt (3.1.10) better_errors (2.1.1) coderay (>= 1.0.0) @@ -102,6 +111,8 @@ GEM debug_inspector (0.0.2) diff-lcs (1.2.5) docile (1.1.5) + domain_name (0.5.25) + unf (>= 0.0.5, < 1.0.0) dotenv (2.0.2) dotenv-rails (2.0.2) dotenv (= 2.0.2) @@ -145,6 +156,8 @@ GEM activesupport (>= 4.1.0) haml (4.0.7) tilt + http-cookie (1.0.2) + domain_name (~> 0.5) i18n (0.7.0) inline_svg (0.6.1) activesupport (>= 4.0.4) @@ -186,6 +199,7 @@ GEM net-scp (1.2.1) net-ssh (>= 2.6.5) net-ssh (3.0.1) + netrc (0.10.3) nokogiri (1.6.6.2) mini_portile (~> 0.6.0) normalize-rails (3.0.3) @@ -242,6 +256,10 @@ GEM rainbow (2.0.0) rake (10.4.2) redcarpet (3.3.3) + rest-client (1.8.0) + http-cookie (>= 1.0.2, < 2.0) + mime-types (>= 1.16, < 3.0) + netrc (~> 0.7) rspec-core (3.3.2) rspec-support (~> 3.3.0) rspec-expectations (3.3.1) @@ -334,6 +352,7 @@ DEPENDENCIES binding_of_caller bourbon capybara-screenshot + cloudinary! coffee-rails database_cleaner dotenv-rails diff --git a/app/helpers/photos_helper.rb b/app/helpers/photos_helper.rb index 7fce6d2..861f12f 100644 --- a/app/helpers/photos_helper.rb +++ b/app/helpers/photos_helper.rb @@ -1,5 +1,5 @@ module PhotosHelper def link_to_photo(photo) - link_to '', photo.image.url, rel: 'photos', class: 'fancy', data: { id: photo.id } + link_to '', "#{photo.image.url}.jpg", rel: 'photos', class: 'fancy', data: { id: photo.id } end end diff --git a/app/models/photo.rb b/app/models/photo.rb index e92c7ce..316143c 100644 --- a/app/models/photo.rb +++ b/app/models/photo.rb @@ -1,10 +1,8 @@ +require 'cloudinary_image' + class Photo < ActiveRecord::Base has_and_belongs_to_many :categories - dragonfly_accessor :image - - validates :image, presence: true - paginates_per 11 scope :enabled, -> { where(enabled: true) } @@ -19,6 +17,15 @@ class Photo < ActiveRecord::Base title end + def image=(image_path) + @image = CloudinaryImage.create(image_path) + self.image_cloudinary_id = @image.id + end + + def image + @image ||= CloudinaryImage.new(image_cloudinary_id) + end + def log_view if views.nil? self.views = 1 diff --git a/app/views/fields/image/_form.html.erb b/app/views/fields/image/_form.html.erb index 15844d9..a01921e 100644 --- a/app/views/fields/image/_form.html.erb +++ b/app/views/fields/image/_form.html.erb @@ -1,3 +1,3 @@ <%= f.label field.attribute %> -<%= image_tag field.data.thumb('32x32#').url, alt: nil if field.data.present? %> +<%= image_tag field.data.url(:admin_form), alt: nil if field.data.present? %> <%= f.file_field field.attribute %> diff --git a/app/views/fields/image/_index.html.erb b/app/views/fields/image/_index.html.erb index 52e1062..d963fc0 100644 --- a/app/views/fields/image/_index.html.erb +++ b/app/views/fields/image/_index.html.erb @@ -1 +1 @@ -<%= image_tag field.data.thumb('50x50#').url, alt: nil %> +<%= image_tag field.data.url(:admin_index), alt: nil if field.data.present? %> diff --git a/app/views/fields/image/_show.html.erb b/app/views/fields/image/_show.html.erb index d1bbc97..da6be9e 100644 --- a/app/views/fields/image/_show.html.erb +++ b/app/views/fields/image/_show.html.erb @@ -1 +1 @@ -<%= image_tag field.data.thumb('400x400').url %> +<%= image_tag field.data.url(:admin_show) if field.data.present? %> diff --git a/app/views/shared/_photo_styles.html.erb b/app/views/shared/_photo_styles.html.erb index 59f6b84..22d38cb 100644 --- a/app/views/shared/_photo_styles.html.erb +++ b/app/views/shared/_photo_styles.html.erb @@ -1,18 +1,22 @@ diff --git a/config/cloudinary.yml b/config/cloudinary.yml new file mode 100644 index 0000000..0e26da2 --- /dev/null +++ b/config/cloudinary.yml @@ -0,0 +1,19 @@ +--- +development: + cloud_name: <%= ENV['CLOUDINARY_CLOUD_NAME'] %> + api_key: <%= ENV['CLOUDINARY_API_KEY'] %> + api_secret: <%= ENV['CLOUDINARY_API_SECRET'] %> + enhance_image_tag: true + static_image_support: false +production: + cloud_name: <%= ENV['CLOUDINARY_CLOUD_NAME'] %> + api_key: <%= ENV['CLOUDINARY_API_KEY'] %> + api_secret: <%= ENV['CLOUDINARY_API_SECRET'] %> + enhance_image_tag: true + static_image_support: true +test: + cloud_name: <%= ENV['CLOUDINARY_CLOUD_NAME'] %> + api_key: <%= ENV['CLOUDINARY_API_KEY'] %> + api_secret: <%= ENV['CLOUDINARY_API_SECRET'] %> + enhance_image_tag: true + static_image_support: false diff --git a/db/migrate/20151028124718_add_image_cloudinary_id_to_photos.rb b/db/migrate/20151028124718_add_image_cloudinary_id_to_photos.rb new file mode 100644 index 0000000..37892aa --- /dev/null +++ b/db/migrate/20151028124718_add_image_cloudinary_id_to_photos.rb @@ -0,0 +1,5 @@ +class AddImageCloudinaryIdToPhotos < ActiveRecord::Migration + def change + add_column :photos, :image_cloudinary_id, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 15320f0..8013316 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20151023165644) do +ActiveRecord::Schema.define(version: 20151028124718) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -43,18 +43,19 @@ ActiveRecord::Schema.define(version: 20151023165644) do end create_table "photos", force: :cascade do |t| - t.string "flickr_url", limit: 255 + t.string "flickr_url", limit: 255 t.datetime "created_at" t.datetime "updated_at" - t.string "title", limit: 255 + t.string "title", limit: 255 t.text "description" t.integer "sort" - t.boolean "featured", default: false - t.boolean "enabled", default: true + t.boolean "featured", default: false + t.boolean "enabled", default: true t.datetime "taken_at" - t.integer "views", default: 0 - t.string "image_uid", limit: 255 - t.string "image_name", limit: 255 + t.integer "views", default: 0 + t.string "image_uid", limit: 255 + t.string "image_name", limit: 255 + t.string "image_cloudinary_id" end create_table "sessions", force: :cascade do |t| diff --git a/lib/cloudinary_image.rb b/lib/cloudinary_image.rb new file mode 100644 index 0000000..e563f51 --- /dev/null +++ b/lib/cloudinary_image.rb @@ -0,0 +1,41 @@ +class CloudinaryImage + FORMATS = { + admin_form: { width: 32, height: 32, crop: :fill }, + admin_index: { width: 50, height: 50, crop: :fill }, + admin_show: { width: 400, height: 400, crop: :fit }, + + size2: { width: 56, height: 56, crop: :fill }, + size3: { width: 84, height: 84, crop: :fill }, + size5: { width: 140, height: 140, crop: :fill }, + size8: { width: 224, height: 224, crop: :fill }, + size11: { width: 308, height: 308, crop: :fill }, + size17: { width: 476, height: 476, crop: :fill }, + + size2x2: { width: 112, height: 112, crop: :fill }, + size3x2: { width: 168, height: 168, crop: :fill }, + size5x2: { width: 280, height: 280, crop: :fill }, + size8x2: { width: 448, height: 448, crop: :fill }, + size11x2: { width: 616, height: 616, crop: :fill }, + size17x2: { width: 952, height: 952, crop: :fill } + } + + attr_reader :id + + def initialize(id) + @id = id + end + + def self.create(upload) + id = upload.original_filename.split('.').first + Cloudinary::Uploader.upload(upload, public_id: id) + new(id) + end + + def url(format = nil) + if FORMATS[format].present? + Cloudinary::Utils.cloudinary_url(id, FORMATS[format].dup) + else + Cloudinary::Utils.cloudinary_url(id) + end + end +end