aboutsummaryrefslogtreecommitdiffstats
path: root/app/models/active_storage/service/gcs_service.rb
diff options
context:
space:
mode:
authorDavid Heinemeier Hansson <david@loudthinking.com>2017-07-22 09:47:24 -0500
committerDavid Heinemeier Hansson <david@loudthinking.com>2017-07-22 09:47:24 -0500
commitd50679f4eefde1aca1ab71ba3c0109739cfdff3f (patch)
treeac9034fe7c4aa64cd5e90ecebc346d478917387c /app/models/active_storage/service/gcs_service.rb
parent5b7c31c23a708de77b3d73b68aec0ba99c8be861 (diff)
downloadrails-d50679f4eefde1aca1ab71ba3c0109739cfdff3f.tar.gz
rails-d50679f4eefde1aca1ab71ba3c0109739cfdff3f.tar.bz2
rails-d50679f4eefde1aca1ab71ba3c0109739cfdff3f.zip
Move models and jobs to the app setup
Follow engine conventions more closely
Diffstat (limited to 'app/models/active_storage/service/gcs_service.rb')
-rw-r--r--app/models/active_storage/service/gcs_service.rb71
1 files changed, 71 insertions, 0 deletions
diff --git a/app/models/active_storage/service/gcs_service.rb b/app/models/active_storage/service/gcs_service.rb
new file mode 100644
index 0000000000..7053a130c0
--- /dev/null
+++ b/app/models/active_storage/service/gcs_service.rb
@@ -0,0 +1,71 @@
+require "google/cloud/storage"
+require "active_support/core_ext/object/to_query"
+
+class ActiveStorage::Service::GCSService < ActiveStorage::Service
+ attr_reader :client, :bucket
+
+ def initialize(project:, keyfile:, bucket:)
+ @client = Google::Cloud::Storage.new(project: project, keyfile: keyfile)
+ @bucket = @client.bucket(bucket)
+ end
+
+ def upload(key, io, checksum: nil)
+ instrument :upload, key, checksum: checksum do
+ begin
+ bucket.create_file(io, key, md5: checksum)
+ rescue Google::Cloud::InvalidArgumentError
+ raise ActiveStorage::IntegrityError
+ end
+ end
+ end
+
+ # FIXME: Add streaming when given a block
+ def download(key)
+ instrument :download, key do
+ io = file_for(key).download
+ io.rewind
+ io.read
+ end
+ end
+
+ def delete(key)
+ instrument :delete, key do
+ file_for(key)&.delete
+ end
+ end
+
+ def exist?(key)
+ instrument :exist, key do |payload|
+ answer = file_for(key).present?
+ payload[:exist] = answer
+ answer
+ end
+ end
+
+ def url(key, expires_in:, disposition:, filename:)
+ instrument :url, key do |payload|
+ query = { "response-content-disposition" => "#{disposition}; filename=\"#{filename}\"" }
+ generated_url = file_for(key).signed_url(expires: expires_in, query: query)
+
+ payload[:url] = generated_url
+
+ generated_url
+ end
+ end
+
+ def url_for_direct_upload(key, expires_in:, content_type:, content_length:)
+ instrument :url, key do |payload|
+ generated_url = bucket.signed_url key, method: "PUT", expires: expires_in,
+ content_type: content_type
+
+ payload[:url] = generated_url
+
+ generated_url
+ end
+ end
+
+ private
+ def file_for(key)
+ bucket.file(key)
+ end
+end