Skip to content

Very incomplete first stab #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ gem 'httparty'

gem 'aws-sdk', '~> 2', require: false
gem 'google-cloud-storage', require: false
gem 'mini_magick'
2 changes: 2 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ GEM
mime-types (3.1)
mime-types-data (~> 3.2015)
mime-types-data (3.2016.0521)
mini_magick (4.8.0)
mini_portile2 (2.1.0)
minitest (5.10.2)
multi_json (1.12.1)
Expand Down Expand Up @@ -143,6 +144,7 @@ DEPENDENCIES
byebug
google-cloud-storage
httparty
mini_magick
rake
sqlite3

Expand Down
22 changes: 22 additions & 0 deletions lib/active_storage/controllers/variants_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
require "action_controller"
require "active_storage/blob"

class ActiveStorage::Controllers::VariantsController < ActionController::Base
def show
if blob_key = decode_verified_key
variant = ActiveStorage::Variant.lookup(blob_key: blob_key, variation_key: params[:variation_key])
redirect_to variant.url
else
head :not_found
end
end

private
def decode_verified_key
ActiveStorage::VerifiedKeyWithExpiration.decode(params[:encoded_key])
end

def disposition_param
params[:disposition].presence_in(%w( inline attachment )) || 'inline'
end
end
59 changes: 36 additions & 23 deletions lib/active_storage/engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,29 +33,42 @@ class Engine < Rails::Engine # :nodoc:
end
end

config.after_initialize do |app|
if config_choice = app.config.active_storage.service
config_file = Pathname.new(Rails.root.join("config/storage_services.yml"))
raise("Couldn't find Active Storage configuration in #{config_file}") unless config_file.exist?

require "yaml"
require "erb"

configs =
begin
YAML.load(ERB.new(config_file.read).result) || {}
rescue Psych::SyntaxError => e
raise "YAML syntax error occurred while parsing #{config_file}. " \
"Please note that YAML must be consistently indented using spaces. Tabs are not allowed. " \
"Error: #{e.message}"
end

ActiveStorage::Blob.service =
begin
ActiveStorage::Service.configure config_choice, configs
rescue => e
raise e, "Cannot load `Rails.config.active_storage.service`:\n#{e.message}", e.backtrace
end
initializer "active_storage.verifiers" do
require "active_storage/verified_key_with_expiration"
require "active_storage/variant"

config.after_initialize do |app|
ActiveStorage::VerifiedKeyWithExpiration.verifier = \
ActiveStorage::Variant.verifier = \
Rails.application.message_verifier('ActiveStorage')
end
end

initializer "active_storage.services" do
config.after_initialize do |app|
if config_choice = app.config.active_storage.service
config_file = Pathname.new(Rails.root.join("config/storage_services.yml"))
raise("Couldn't find Active Storage configuration in #{config_file}") unless config_file.exist?

require "yaml"
require "erb"

configs =
begin
YAML.load(ERB.new(config_file.read).result) || {}
rescue Psych::SyntaxError => e
raise "YAML syntax error occurred while parsing #{config_file}. " \
"Please note that YAML must be consistently indented using spaces. Tabs are not allowed. " \
"Error: #{e.message}"
end

ActiveStorage::Blob.service =
begin
ActiveStorage::Service.configure config_choice, configs
rescue => e
raise e, "Cannot load `Rails.config.active_storage.service`:\n#{e.message}", e.backtrace
end
end
end
end
end
Expand Down
1 change: 1 addition & 0 deletions lib/active_storage/routes.rb
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
get "/rails/active_storage/disk/:encoded_key/*filename" => "active_storage/disk#show", as: :rails_disk_blob
get "/rails/active_storage/variants/:encoded_key/:encoded_transformation/*filename" => "active_storage/controllers/variants#show", as: :rails_blob_variant
post "/rails/active_storage/direct_uploads" => "active_storage/direct_uploads#create", as: :rails_direct_uploads
52 changes: 52 additions & 0 deletions lib/active_storage/variant.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
require "active_storage/blob"
require "mini_magick"

class ActiveStorage::Variant
class_attribute :verifier

attr_reader :blob, :variation
delegate :service, to: :blob

def self.lookup(blob_key:, variation_key:)
new ActiveStorage::Blob.find_by!(key: blob_key), variation: verifier.verify(variation_key)
end

def self.encode_key(variation)
verifier.generate(variation)
end

def initialize(blob, variation:)
@blob, @variation = blob, variation
end

def url(expires_in: 5.minutes, disposition: :inline)
perform unless exist?
service.url key, expires_in: expires_in, disposition: disposition, filename: blob.filename
end

def key
verifier.generate(variation)
end

private
def perform
upload_variant transform(download_blob)
end

def download_blob
service.download(blob.key)
end

def upload_variant(variation)
service.upload key, variation
end

def transform(io)
# FIXME: Actually do a variant based on the variation
File.open MiniMagick::Image.read(io).resize("500x500").path
end

def exist?
service.exist?(key)
end
end
2 changes: 1 addition & 1 deletion lib/active_storage/verified_key_with_expiration.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
class ActiveStorage::VerifiedKeyWithExpiration
class_attribute :verifier, default: defined?(Rails) ? Rails.application.message_verifier('ActiveStorage') : nil
class_attribute :verifier

class << self
def encode(key, expires_in: nil)
Expand Down
Binary file added test/fixtures/files/racecar.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions test/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
require "active_storage/verified_key_with_expiration"
ActiveStorage::VerifiedKeyWithExpiration.verifier = ActiveSupport::MessageVerifier.new("Testing")

require "active_storage/variant"
ActiveStorage::Variant.verifier = ActiveSupport::MessageVerifier.new("Testing")

class ActiveSupport::TestCase
private
def create_blob(data: "Hello world!", filename: "hello.txt", content_type: "text/plain")
Expand Down
16 changes: 16 additions & 0 deletions test/variation_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
require "test_helper"
require "database/setup"
require "active_storage/variant"

class ActiveStorage::VariationTest < ActiveSupport::TestCase
test "square variation" do
blob = ActiveStorage::Blob.create_after_upload! \
io: File.open(File.expand_path("../fixtures/files/racecar.jpg", __FILE__)), filename: "racecar.jpg", content_type: "image/jpeg"

variation_key = ActiveStorage::Variant.encode_key(resize: "500x500")

variant = ActiveStorage::Variant.lookup(blob_key: blob.key, variation_key: variation_key)

assert_match /racecar.jpg/, variant.url
end
end