A workaround to pre-populate file_field? - ruby-on-rails

I don't think you can literally pre-populate the file_field so I've been struggling with a workaround for the same end goal, which is to take an image already uploaded to the application via User A and then for User B to be able to save that same image as his own too, similar to pinterest.
This is what I've tried:
index
<%= link_to new_inspiration_path(inspiration_image: inspiration.image) %>
controller
def new
#inspiration = current_user.inspirations.build
#inspiration.image = URI.parse(params[:inspiration_image])
end
server
Started GET "/inspirations/new?inspiration_image=%2Fsystem%2Finspirations%2Fimages%2F000%2F000%2F069%2Foriginal%2Frule_1.jpg%3F1478260961" for 127.0.0.1 at 2016-11-04 08:10:41 -0400
Processing by InspirationsController#new as */*
Parameters: {"inspiration_image"=>"/system/inspirations/images/000/000/069/original/rule_1.jpg?1478260961"} # For example, this is the image url I'm trying to duplicate for User B
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 129]]
Inspiration Load (0.4ms) SELECT "inspirations".* FROM "inspirations" WHERE "inspirations"."id" IS NULL LIMIT 1
Completed 400 Bad Request in 6ms
_form
<%= simple_form_for(#inspiration, html: { data: { modal: true } }) do |f| %>
<%= image_tag #inspiration.image.url if #inspiration.image.present? %> # I get error: ActionController::ParameterMissing (param is missing or the value is empty: inspiration):
<%= f.file_field :image %>
<% end %>
model
class Inspiration < ActiveRecord::Base
has_attached_file :image, :styles => { :medium => "300x300>", :small => "150x150>" }
validates_attachment_content_type :image, :content_type => ["image/jpg", "image/jpeg", "image/png", "image/gif"]
belongs_to :user
def image_remote_url=(url_value)
self.image = URI.parse(url_value).to_s unless url_value.blank?
super
end
end

Change #inspiration.image assignment to #inspiration.image = URI.parse(params[:inspiration_image])
More info can be found here: https://github.com/thoughtbot/paperclip/wiki/Attachment-downloaded-from-a-URL
EDIT:
Change model according to the info in the link:
attr_reader :image_remote_url
#image_remote_url = url_value
Remove super call
Change assignment to #inspiration.image_remote_url = params[:inspiration_image]

Related

Why image_tag doesn't show image while link_to shows?

I want to display image in my cart via paperclip gem but it won't works with image_tag while with link_to work fine
This works:
<% simple_current_order.line_items.all.each do |line_item| %>
<%= link_to mini_image(line_item.variant)), product_path(line_item) %>
<% end %>
While this not
<% simple_current_order.line_items.all.each do |line_item| %>
<%= image_tag mini_image(line_item.variant) %>
<% end %>
image.rb model
module Spree
class Image < Asset
validate :no_attachment_errors
has_attached_file :attachment,
styles: { mini: '48x48>', small: '100x100>', product: '240x240>', large: '600x600>' },
default_style: :product,
url: '/spree/products/:id/:style/:basename.:extension',
path: ':rails_root/public/spree/products/:id/:style/:basename.:extension',
convert_options: { all: '-strip -auto-orient -colorspace sRGB' }
validates_attachment :attachment,
:presence => true,
:content_type => { :content_type => %w(image/jpeg image/jpg image/png image/gif) }
# save the w,h of the original image (from which others can be calculated)
# we need to look at the write-queue for images which have not been saved yet
after_post_process :find_dimensions
#used by admin products autocomplete
def mini_url
attachment.url(:mini, false)
end
def find_dimensions
temporary = attachment.queued_for_write[:original]
filename = temporary.path unless temporary.nil?
filename = attachment.path if filename.blank?
geometry = Paperclip::Geometry.from_file(filename)
self.attachment_width = geometry.width
self.attachment_height = geometry.height
end
# if there are errors from the plugin, then add a more meaningful message
def no_attachment_errors
unless attachment.errors.empty?
# uncomment this to get rid of the less-than-useful interim messages
# errors.clear
errors.add :attachment, "Paperclip returned errors for file '#{attachment_file_name}' - check ImageMagick installation or image source file."
false
end
end
end
end
It can't find image with image tag, anyone know why?

how to load and validate the video using paperclip-Rails

please help solve the problem.
using a paperclip I organized upload images. it works.
Now I would like to organize a video upload. I changed this model:
model:
class Video < ActiveRecord::Base
validates :title, presence: true
validates :video, presence: true
belongs_to :user
has_attached_file :video,
:styles => { :medium => "300x300>", :thumb => "100x100>" },
:default_url => "/images/:style/missing.png"
validates_attachment_content_type :video, :content_type => /\Avideo\/.*\Z/
validates_attachment_file_name :video, :matches => [/3gp\Z/, /mp4\Z/, /flv\Z/]
validate :file_size_validation, :if => "video?"
def file_size_validation
errors[:video] << "should be less than 2MB" if video.size.to_i > 30.megabytes
end
end
video controller:
def create
#video = Video.new(video_params)
if #video.save
#video.update_attributes(user: current_user)
flash[:success] = :video_created
redirect_to #video
else
flash.now[:error] = :user_not_created
render 'new'
end
end
form:
<%= form_for(#video) do |f| %>
<%= f.text_field :title %>
<%= f.file_field :video %>
<%= f.submit %>
<% end %>
after attempting to upload the video I get the console the following error message:
Started POST "/videos" for 127.0.0.1 at 2015-07-23 14:17:32 +0300
Processing by VideosController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"RF3w8PzZ9LZ4pdqRPqRvHMQ+nYDL4om0YHAMlzTm8tf3iFmVmKxXSYKap3C0ogEnOkifm9i01oXs/rTX9zmtPA==", "video"=>{"title"=>"tty", "video"=>#<ActionDispatch::Http::UploadedFile:0x007f6624f10770 #tempfile=#<Tempfile:/tmp/RackMultipart20150723-13428-u7s8i8.flv>, #original_filename="mmm.flv", #content_type="video/x-flv", #headers="Content-Disposition: form-data; name=\"video[video]\"; filename=\"mmm.flv\"\r\nContent-Type: video/x-flv\r\n">}, "commit"=>"Create Video"}
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT 1 [["id", 8]]
Command :: file -b --mime '/tmp/c4efd5020cb49b9d3257ffa0fbccc0ae20150723-13428-6gn39i.flv'
Command :: identify -format '%wx%h,%[exif:orientation]' '/tmp/c4efd5020cb49b9d3257ffa0fbccc0ae20150723-13428-1eailfd.flv[0]' 2>/dev/null
[paperclip] An error was received while processing: #<Paperclip::Errors::NotIdentifiedByImageMagickError: Paperclip::Errors::NotIdentifiedByImageMagickError>
Command :: identify -format '%wx%h,%[exif:orientation]' '/tmp/c4efd5020cb49b9d3257ffa0fbccc0ae20150723-13428-1eailfd.flv[0]' 2>/dev/null
[paperclip] An error was received while processing: #<Paperclip::Errors::NotIdentifiedByImageMagickError: Paperclip::Errors::NotIdentifiedByImageMagickError>
(0.2ms) BEGIN
Command :: file -b --mime '/tmp/c4efd5020cb49b9d3257ffa0fbccc0ae20150723-13428-khstwa.flv'
(0.2ms) ROLLBACK
on screen displays the following error message:
Video Paperclip::Errors::NotIdentifiedByImageMagickError
wherein imageMagik installed in my system:
sudo apt-get install imagemagick
db:
create_table "videos", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "title"
t.integer "user_id"
t.string "video_file_size"
t.string "video_updated_at"
t.string "video_file_name"
t.string "video_content_type"
end
Working with image with paperclip and with video is different.Though the common point is that it will help you tu send the uploaded data to the server but you need to handle it with some processor.Just like you use ImageMagick for images,you should use FFMPEG to encode/decode video.
i will share the code which i usually use for video..but before that ,you must set up ffmpeg to handle all formats of video just like you did for Imagemagick.
here is set up for ffmpeg and dont forget to provide path in environment file using which ffmpeg
you need ffmpeg-paperclip as well for coding/decoding videos.
video.rb
##using s3
##convert the video into mp4 and also get screenshot of video at 5 sec
##add your own formats that you want
has_attached_file :video,
:styles => {
:mp4video => { :geometry => '520x390', :format => 'mp4',
:convert_options => { :output => { :vcodec => 'libx264',
:vpre => 'ipod640', :b => '250k', :bt => '50k',
:acodec => 'libfaac', :ab => '56k', :ac => 2 } } },
:preview => { :geometry => '300x300>', :format => 'jpg', :time => 5 }
},
processors: [:ffmpeg],
:storage => :s3,
:size => { :in => 0..25.megabytes },
:s3_permissions => :public_read,
:s3_credentials => S3_CREDENTIALS
validates_attachment_content_type :video, :content_type => /\Avideo\/.*\Z/
validates_presence_of :video
once you have saved the video,you need to use some plugins to show the video player along with your video in show action.You can use Mediaelement.js(my favorite).Download it,dump it in js/css files accordingly,Include it in application.js and application.css.
in your show.html.erb
##add video tag to show video
<video autobuffer="autobuffer" preload="auto" style="width:100%;height:100%;" controls="controls" width="100%" height="100%" poster="<%= #video.video.url(:preview)%>" >
<source src="<%= #video.video.url%>" />
<%if #video.video.expiring_url(:mp4video).present? %>
<source type="video/mp4" src="<%= #video.video.url(:mp4video)%>" />
<%end%>
</video>
##javascript to handle video player
$('video').mediaelementplayer();
paperclip's processor is designed for images, so it cannot handle videos. You're getting the error saying that ImageMagick did not recognize this file as an image. Fair enough, it's not an image!
Still, you could write a post-processor yourself, and paperclip's github page offers an example of the syntax that would be needed to call a custom processing class:
has_attached_file :scan, :styles => { :text => { :quality => :better } },
:processors => [:ocr]
This defines a variation of the attachment called text that is obtained by processing the uploaded file with a (hypothetical) Paperclip::Ocr class with options hash { :quality => :better }
Choice of the exact conversion tool is up to you, but you do want to make sure that processing is done asynchronously, not inside the usual request-response cycle, you may want to use a background queue like Sidekiq, Que or Rails' (4.2+) ActiveJob.

Paperclip: Content Type Spoof trying to upload .gpx files

Apologies if this has been answered and I failed to find it. Any direction would be greatly appreciated.
Using Rails 4.1.4, Paperclip 4.2.0 and Simple Form 3.0.2.
After Submit, I get has an extension that does not match its contents output in the form error message.
In the server window:
Started POST "/routes" for 127.0.0.1 at 2014-08-28 15:18:25 +0700
Processing by RoutesController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"5BCHGBkwQH4mlnTVjy/PpD53mJKJpSmBXwXT/oul7yY=", "route"=>{"track_attributes"=>{"gpx"=>#<ActionDispatch::Http::UploadedFile:0x007fa89c9cd348 #tempfile=#<Tempfile:/var/folders/_g/6shs5yrj36n960wpt880ysl80000gn/T/RackMultipart20140828-42106-vi71nb>, #original_filename="Serge's tracks.gpx", #content_type="application/octet-stream", #headers="Content-Disposition: form-data; name=\"route[track_attributes][gpx]\"; filename=\"Serge's tracks.gpx\"\r\nContent-Type: application/octet-stream\r\n">}, "title"=>"Serge track", "description"=>"loop of hang dong", "distance"=>"", "total_ascent"=>""}, "commit"=>"Create Route"}
Command :: file -b --mime '/var/folders/_g/6shs5yrj36n960wpt880ysl80000gn/T/f55fe48e09c9cc3ee6c6271fe94f407520140828-42106-1hgpby7.gpx'
[paperclip] Content Type Spoof: Filename Serge's_tracks.gpx ([]), content type discovered from file command: application/xml. See documentation to allow this combination.
(0.3ms) BEGIN
Command :: file -b --mime '/var/folders/_g/6shs5yrj36n960wpt880ysl80000gn/T/f55fe48e09c9cc3ee6c6271fe94f407520140828-42106-62bkvh.gpx'
[paperclip] Content Type Spoof: Filename Serge's_tracks.gpx ([]), content type discovered from file command: application/xml. See documentation to allow this combination.
(0.8ms) ROLLBACK
I haven't been able to find said documentation in the Paperclip docs.
Running file Serge\'s\ tracks.gpx --mime-type -b produces application/xml
My MVC looks like this:
class Track < ActiveRecord::Base
belongs_to :route
has_attached_file :gpx
validates_attachment_content_type :gpx, :content_type => /application\/xml/
end
class Route < ActiveRecord::Base
has_one :track, dependent: :destroy
accepts_nested_attributes_for :track
validates :title, presence: true
end
Inside RoutesController
def new
#route = Route.new
#route.track = Track.new
end
def create
#route = Route.new(route_params)
end
def route_params
params.require(:route).permit(:title, :description, :distance, :total_ascent, track_attributes: [:gpx])
end
The simple_form:
= simple_form_for #route do |r|
= r.simple_fields_for :track do |t|
= t.input :gpx
= r.input :title
= r.input :description
= r.input :distance
= r.input :total_ascent
= r.button :submit
As mentioned in this post: Paperclip gem spoofing error? and this article http://robots.thoughtbot.com/prevent-spoofing-with-paperclip, the problem was solved by apparently bypassing the command file -b --mime-type that is called by Paperclip.
To do this I created a paperclip.rb file in config/initializers.
Paperclip.options[:content_type_mappings] = {
:gpx => 'application/xml'
}
While the problem is solved, I am still confused as to why the problem existed when the file command was returning a correct result, and also curious where the #content_type="application/octet-stream" in the params is coming from.

Paperclip doesn't store in a proper format fetched image by url

When I trying to fetch a facebook image by the graph URL(https://graph.facebook.com), paperclip stores avatar_image_name as "picture" in the database. The example of code:
img = UserImages.new
img.avatar = URI.parse('https://graph.facebook.com/666980153384194/picture?type=large')
img.save
The MySQL query in a console log:
=> #<URI::HTTPS:0x00000009954490 URL:https://graph.facebook.com/666980153384194/picture?type=large>
irb(main):009:0> img.save
(0.0ms) BEGIN
SQL (0.0ms) INSERT INTO `user_images` (`avatar_content_type`, `avatar_file_name`, `avatar_file_size`, `avatar_updated
_at`, `created_at`, `updated_at`) VALUES ('image/jpeg', 'picture', 6157, '2014-07-08 13:55:53', '2014-07-08 13:56:02', '
2014-07-08 13:56:02')
(29.1ms) COMMIT
As you can see fetched image file stored by the name 'picture'. But if to fetch image by Direct URL like:
https://scontent-a-lax.xx.fbcdn.net/hphotos-prn2/v/t1.0-9/10478546_662150043867205_2640371404472615909_n.jpg?oh=cb2fe9d421fef3d7d2220bb48a2a36e2&oe=5418E8FB
The fetched image stored as:
(0.0ms) BEGIN
Command :: file -b --mime "C:/Users/Windows/AppData/Local/Temp/f1620d075c0642a77f7b98e532d8a8eb20140708-1040-1h5z4e6.jpg
"
SQL (1.0ms) INSERT INTO `user_images` (`avatar_content_type`, `avatar_file_name`, `avatar_file_size`, `avatar_updated
_at`, `created_at`, `updated_at`) VALUES ('image/jpeg', '10478546_662150043867205_2640371404472615909_n.jpg', 25862, '20
14-07-08 14:02:45', '2014-07-08 14:02:49', '2014-07-08 14:02:49')
(34.1ms) COMMIT
=> true
Any advise(solution) will be highly appreciated.
The source of UserImages class:
class UserImages < ActiveRecord::Base
belongs_to :imageable ,polymorphic: true
has_attached_file :avatar,
:styles => { :medium => "300x300>", :thumb => "125x125>" },
:path => ":rails_root/public/images/users/:id/:style/:hash.:extension",
:default_url => "/images/normal/missing.jpg",
:url => "/images/users/:id/:style/:hash.:extension",
:hash_secret => "EWRWerrew234UTY"
validates_attachment :avatar, :content_type => { :content_type => ["image/jpeg", "image/gif", "image/png"] },
:size => { :in => 0..5.megabytes }
end
There is no problem in both fetching URLs.... Both working fine...
The difference is only because paperclip generates the file name from the last part of the URL...
So in the first URL
https://graph.facebook.com/666980153384194/picture?type=large
And in the second URL
https://scontent-a-lax.xx.fbcdn.net/hphotos-prn2/v/t1.0-9/10478546_662150043867205_2640371404472615909_n.jpg?oh=cb2fe9d421fef3d7d2220bb48a2a36e2&oe=5418E8FB
I've bolded the part of the URL that paperclip is using to generate filename.... And in both cases you shouldn't really bother yourself with the file name... Since you can do any operation you want thought paperclip.
And you can make sure that the files are uploaded by checking the path public/images/users/:id (the paperclip path configuration)

How to specify :path and :url to save img in Paperclip, Rails 3.0.12

I'm using Paperclip with my Rails 3.0 app in order to add an avatar to a user, and it won't save the image because the paths are off. Heres what I get:
Started GET "/profilepics/small/missing.png" for 127.0.0.1 at 2012-04-11 23:38:29 -0700
ActionController::RoutingError (No route matches "/profilepics/small/missing.png"):
My user model has:
has_attached_file :profilepic, :styles => { :small => "150x150>" }
What should I put for :path => & :url => ?
Form looks like :
<% form_for #user, :html => { :multipart => true } do |f| %>
<%= f.file_field :profilepic %>
<% end %>
Logs look like :
Started GET "/system/profilepics/small/missing.png" for 127.0.0.1 at 2012-04-12 00:33:51 -0700
ActionController::RoutingError (No route matches "/system/profilepics/small/missing.png"):
Rendered /usr/lib/ruby/gems/1.9.1/gems/actionpack-3.0.12/lib/action_dispatch/middleware/templates/rescues/routing_error.erb within rescues/layout (1.2ms)
See my sample:
has_attached_file :avatar, :styles => { :thumb => "50x50#", :large => "1000x1000>", :medium => "200x200#" },
:default_url => "/system/avatars/:style/missing.png",
:url => "/system/:attachment/:id/:style_:filename",
:path => ":rails_root/public/system/:attachment/:id/:style_:filename"
:default_url - is the path for the default image, when the user didn't upload any avatar
"#" - this symbol is to crop image
then you can show your images as such:
<%=image_tag(#user.avatar.url(:thumb))%>
<%=image_tag(#user.avatar.url(:medium))%>
Works now!!!
For people struggling with the same issue, here's a few important things to ALWAYS make sure and check:
In your form, always specify { :multipart => true } otherwise, the form won't accept file attachments.
<%= form_for #user, :html => **{ :multipart => true }** do |f| %>
In your user.rb (or whatever model you want to add attachments to ), make attr_accessible :photo (or whatever you name your attachment)
ALWAYS restart your server after installing a new Gem.
:) Thanks guys!!!!
There is no need to given url and path option if you simply want to display an image.
Use this line in show page and it will display image...
<%=image_tag(#user.profilepic.url(:small))%>
And enjoy..............

Resources