Rails 6 Active Storage to S3 - ruby-on-rails

I'm trying to take a URL of an image that I get back from an API and upload that to an S3 bucket:
Here's my config/environments/production.rb
config.active_storage.service = :amazon
stories_controller.rb
#url = response.dig("data", 0, "url")
require 'open-uri'
downloaded_image = URI.open(#url)
#story.cover.attach(io: downloaded_image, filename: #story.id.to_s + "-cover.jpg")
#story.save!
This is the view:
<%= image_tag #story.cover, :class => "swiper-lazy home_video" %>
And here's the output it generates:
> <img class="swiper-lazy home_video swiper-lazy-loaded"
> src="https://{myURL}/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBEQT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--ace6ec16db514c2645008bcd4834618a8575136b/14-cover.jpg">
How can I get the image to upload to S3?

Related

Images uploaded into ActionText text area not linking correctly to S3

I am using ActionText with image upload using the image_processing gem. However, when uploading images they do not go to S3 which is set in Active Storage.
All other image uploads work fine and go into my S3 buckets as expected. It is just images uploaded into the ActionText editor that does not use the S3 URL. They do go into the correct buckets, however. It is just the URL that I can't change or get access to in the blob element.
I assume there is a setting in an initializer or config that I have not been able to find but I can't find it through the documentation or google.
The URL the blob is currently using is the rail/active_storage/ storage URL and I need it to use the S3 URL I have set in the active_storage.yml file.
Turns out I could edit the URL in the _blob.html.erb file. First I had to check if I was in Production or not. Once I verify that I was able to construct the URL to grab from S3 using the blob.key.
<% if blob.representable? %>
<% if Rails.env == 'production' %>
<img class: "post-actiontext-image" src="https://<%= ENV['S3_BUCKET'] %>.s3-<%= ENV['AWS_REGION'] %>.amazonaws.com/<%= blob.key %>" />
<% else %>
<%= image_tag blob.representation(resize_to_limit: local_assigns[:in_gallery] ? [ 800, 600 ] : [ 1024, 768 ]), class: "post-actiontext-image" %>
<% end %>
<% end %>

How to change watir chrome pref default_directory to amazon s3?

storage.yml
service: Disk
root: <%= Rails.root.join("tmp/storage") %>
local:
service: Disk
root: <%= Rails.root.join("storage") %>
amazon:
service: S3
access_key_id: <%= ENV['AWS_ACCESS_KEY_ID'] %>
secret_access_key: <%= ENV['AWS_SECRET_ACCESS_KEY'] %>
region: <%= ENV['AWS_REGION'] %>
bucket: <%= ENV['S3_BUCKET_NAME'] %>
confi/enviroments/development.rb
-----------------------------------------------
# Store uploaded files on the local file system (see config/storage.yml for options)
config.active_storage.service = :amazon
Watir Chrome Downaload
-----------------------------------------
prefs = {
download: {
prompt_for_download: false,
default_directory: '/path/to/dir'
}
}
b = Watir::Browser.new :chrome, options: {prefs: prefs}
**My query how to do i set default_directory ro amazon in pref for watir chrom download
**
is this correct --
prefs = {
download: {
prompt_for_download: false,
default_directory: amazon
}
}
Need help :)
enter link description here
If you specify the directory name then it will create the directory in your current directory. Give the full path there. It will work perfectly. I am using this and it's working perfectly for me.

How to include Amazon S3 Content-MD5 request header with Rails S3DirectUpload gem?

I am building a Rails 4 app with admin uploads of large files to Amazon S3. To validate the transfer of the large files, I would like to include the Content-MD5 field in the request header per the Amazon docs:
http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPUT.html
I started with Paperclip + S3 and the MD5 verification is working:
has_attached_file :file,
:storage => :s3,
:bucket => AppSetting.s3_bucket,
:s3_credentials => Proc.new{|a| a.instance.s3_credentials },
:s3_permissions => :private,
:s3_headers => Proc.new{|a| a.s3_headers },
:path => "uploads/:id/:basename.:extension"
def s3_credentials
{:access_key_id => AppSetting.aws_access_key_id, :secret_access_key => AppSetting.aws_secret_access_key}
end
# md5sum is a value entered by the user as a string (hex notation)
# ex: "7d592a3129ab6a867cf6e2eb60f9ef83"
#
def encoded_md5sum
[[md5sum].pack("H*")].pack("m0")
end
def s3_headers
{:content_md5 => encoded_md5sum}
end
With Paperclip, the large file is first uploaded to my server, then transferred to Amazon S3. This blocks the Rails process and consumes redundant bandwidth, so I am trying to use the S3UploadDirect gem to upload the file directly the S3 bucket:
https://github.com/waynehoover/s3_direct_upload
This gem is a wrapper around the code from Railscasts episode 383 and uses jquery-fileupload-rails for the actual upload:
<%= s3_uploader_form callback_url: "#{AppSetting.host_base_url}/admin/uploads",
callback_method: "POST",
callback_param: "upload[file_url]",
key: "uploads/{timestamp}-{unique_id}-#{SecureRandom.hex}/${filename}",
key_starts_with: "uploads/",
acl: "private",
bucket: AppSetting.s3_bucket,
aws_access_key_id: AppSetting.aws_access_key_id,
aws_secret_access_key: AppSetting.aws_secret_access_key,
max_file_size: 5.gigabytes,
id: "s3-uploader",
class: "upload-form",
data: {:key => :val} do %>
<%= file_field_tag :file, multiple: true %>
<% end %>
<script id="template-upload" type="text/x-tmpl">
<div id="file-{%=o.unique_id%}" class="upload">
{%=o.name%}
<div class="progress"><div class="bar" style="width: 0%"></div></div>
</div>
</script>
I can upload the file, but I cannot figure out how to pass the Content-MD5 information into the upload request header.

save and show scraping image with nokogiri rails

UPDATE 2
i use nokogiri to download content and images to a rails app. For this, i write the script/scraping.rb file:
require 'open-uri'
page_url = "<site_url>"
url = "<page_of_site_url>"
b = Nokogiri::HTML(open(url))
b.css(".col").each do |item|
img_url = item.at(".field-content a img")['src'].split('?')[0]
root_img_url = URI.join(page_url,img_url).to_s
file = File.open(File.join(Rails.root, 'app', 'assets', 'images', File.basename(root_img_url)), 'wb') do |f|
f.write(open(root_img_url).read)
end
Book.create(
:cover => File.basename(root_img_url),
:title => item.at_css(".views-field-title a").text,
:onsaledate => item.at_css(".date-display-single")['content'])
end
end
then i run the script in the terminal:
rails runner script/scraping.rb
Seconds later, i have my database with the content info, and the images in the folder assets/images.
Thanks to #JoshLewis for his interest and special thanks to #mario_chavez for his help.

ActionMailer - How to add an attachment from s3

Im trying to add attachments to the contact form on this site Im making but I cant get action mailer to attach the uploaded file. I have paperclip uploading the file to S3 but I cant get it to grab the file and attach it to the message.
My app stack is: Heroku, Rails 3, and paperclip uploading to S3, heres what I have so far:
def contact_notification(sender)
#sender = sender
if attachments.count > 0
# Parse the S3 URL into its constituent parts
uri = URI.parse #sender.photo.url(:original).authenticated_url
# Use Ruby's built-in Net::HTTP to read the attachment into memory
response = Net::HTTP.start(uri.host, uri.port) { |http| http.get uri.path }
# Attach it to your outgoing ActionMailer email
attachments[#sender.attachment_file_name] = response.body
end
mail(:to => xxx)
end
What am I doing wrong? Im still a rails noob so Im piecing this together.
A quick note:
Amazon now requires
gem 'aws-sdk', :require => "aws-sdk"
instead of the s3 gem listed above.
If you don't have an s3 account already go get one here:
http://aws.amazon.com/s3/
You need to add this to your contact model:
app/models/contact.rb
has_attached_file :picture,
:styles => {:large => "275x450>"},
:storage => :s3,
:s3_credentials => "#{RAILS_ROOT}/config/s3.yml",
:path => "appname/:attachment/:style/:id.:extension"
Make sure you appname is your rails app name on heroku. And make sure you rename picture to whatever you have named your picture.
Then you need a config file in config/s3.yml.
development:
bucket: bucked_name
access_key_id: key
secret_access_key: secret
production:
bucket: bucked_name
access_key_id: key
secret_access_key: secret
Make sure you get the key and secret correct.
In your gem file make sure you have these gems install :
gem "aws-s3", :require => "aws/s3"
gem "paperclip"
Then in your form you need a file field and declare the form a multipart:
<% form_for(#contact, :html => {:multipart => true}) do |f| %>
<p><%= f.file_field :picture %></p>
<% end %>
And that should do it.
If you don't have an s3 account already go get one here:
http://aws.amazon.com/s3/
You need to add this to your contact model:
app/models/contact.rb
has_attached_file :picture,
:styles => {:large => "275x450>"},
:storage => :s3,
:s3_credentials => "#{RAILS_ROOT}/config/s3.yml",
:path => "appname/:attachment/:style/:id.:extension"
Make sure you appname is your rails app name on heroku. And make sure you rename picture to whatever you have named your picture.
Then you need a config file in config/s3.yml.
development:
bucket: bucked_name
access_key_id: key
secret_access_key: secret
production:
bucket: bucked_name
access_key_id: key
secret_access_key: secret
Make sure you get the key and secret correct.
In your gem file make sure you have these gems install :
gem "aws-s3", :require => "aws/s3"
gem "paperclip"
Then in your form you need a file field and declare the form a multipart:
<% form_for(#contact, :html => {:multipart => true}) do |f| %>
<p><%= f.file_field :picture %></p>
<% end %>
Then mail your contact with the picture. You said that you were using rails 3?
So in your contact model:
class Contact << ActiveRecord::Base
before_save :mail_user
def mailer_user
ContactMailer.contact_notification(#user).deliver
end
end
Then in your mailer (assuming you are on Rails 3):
class ContactMailer < ActionMailer::Base
default :from => "sam#codeglot.com"
def contact_notification(#user)
#subscription = "test"
#url = "test"
mail(:to => "test#test.com",
:subject => "Test")
end
end
So in your mailer view you need to include and image tag like so:
<%= image_tag(#contact.picture(:small)) %>
Then you just need to send you email after a contact is created and include the attachment.

Resources