บันทึกภาพจาก URL โดยคลิปหนีบกระดาษ


คำตอบ:


154

วิธีง่ายๆมีดังนี้

require "open-uri"

class User < ActiveRecord::Base
  has_attached_file :picture

  def picture_from_url(url)
    self.picture = open(url)
  end
end

จากนั้นก็:

user.picture_from_url "http://www.google.com/images/logos/ps_logo2.png"

7
หากคุณจำเป็นต้องใช้การupdate_attributesเปลี่ยนชื่อpicture_from_urlเป็นpicture_url=(value)เช่น
Daniel Rikowski

3
ซึ่งอาจไม่ปลอดภัยเนื่องจากผู้ใช้สามารถโทรuser.picture_from_url('/etc/password')ได้ มันอาจจะดีในสถานการณ์ส่วนใหญ่
David Tuite

1
เพื่อความปลอดภัยคุณควรขึ้นบัญชีขาวของโครงการ URI และบัญชีดำโฮสต์ส่วนตัว
John Douthat

3
ดูคำตอบด้านล่างสำหรับวิธีแก้ปัญหาที่ดียิ่งขึ้น
geekazoid

6
การใช้open(url)ชื่อไฟล์ไม่ถูกต้องเช่นopen-uri20150106-10034-lpd5fm.แทนที่จะเป็นไฟล์ef3a601e_ef3d008b_ef3d0f7e.jpg.
Joshua Pinter

196

ใน Paperclip 3.1.4 จะง่ายกว่าเดิม

def picture_from_url(url)
  self.picture = URI.parse(url)
end

ดีกว่า open (url) เล็กน้อย เนื่องจากเมื่อเปิด (url) คุณจะได้ "stringio.txt" เป็นชื่อไฟล์ จากข้างต้นคุณจะได้รับชื่อที่เหมาะสมของไฟล์ตาม URL กล่าวคือ

self.picture = URI.parse("http://something.com/blah/avatar.png")

self.picture_file_name    # => "avatar.png"
self.picture_content_type # => "image/png"

3
จากคลิปหนีบกระดาษ wiki: github.com/thoughtbot/paperclip/wiki/… ฉันรันในคอนโซลสำเร็จแล้วแอปอยู่ใน heroku
Donny Kurnia

3
FYI สำหรับ S3 urls ฉันยังคงได้รับapplication/octet_streamเป็นไฟล์content_type.
Joshua Pinter

5
หากคุณยังคงใช้คลิปหนีบกระดาษหลังจากเลิกใช้งานคุณอาจต้องตรวจสอบให้แน่ใจว่าตัวโหลด URI IO ได้รับการโหลด: Paperclip :: UriAdapter.register (ในการกำหนดค่าหรือชั่วคราวผ่านคอนโซลหากนั่นคือทั้งหมดที่คุณต้องการ)
Msencenb

แนวทางนี้ถูกต้อง แต่ในเวอร์ชันล่าสุด sintax มีการเปลี่ยนแปลง! ตรวจสอบคำตอบของฉันด้านล่าง => stackoverflow.com/a/56039191/3182171
Diego D

คุณต้องเพิ่มรายการใน initializer github.com/thoughtbot/paperclip/wiki/…
ianpetzer

16

มันไม่ได้ผลสำหรับฉันจนกว่าฉันจะใช้ "เปิด" สำหรับ URI ที่แยกวิเคราะห์ เมื่อฉันเพิ่ม "เปิด" มันใช้งานได้!

def picture_from_url(url)
  self.picture = URI.parse(url).open
end

คลิปหนีบกระดาษของฉันเวอร์ชัน 4.2.1

ก่อนเปิดจะตรวจไม่พบประเภทเนื้อหาที่ถูกต้องเนื่องจากไม่ใช่ไฟล์ มันจะบอกว่า image_content_type: "binary / octet-stream" และแม้ว่าฉันจะแทนที่ด้วยประเภทเนื้อหาที่ถูกต้อง แต่ก็ใช้ไม่ได้


ขอบคุณสำหรับสิ่งนี้! สิ่งที่ฉันพลาดไปเอง
แดน

คุณจะสูญเสียเงินออกจากตำแหน่งถ้าคุณทำเช่นนี้ คุณต้องมี Paperclip :: UriAdapter.register ในตัวเริ่มต้น .. จากนั้นคุณไม่จำเป็นต้องเปิดในตอนท้าย ดูgithub.com/thoughtbot/paperclip/wiki/…
ianpetzer

15

ขั้นแรกให้ดาวน์โหลดภาพด้วยcurbอัญมณีไปที่ a TempFileจากนั้นกำหนดวัตถุ tempfile และบันทึกโมเดลของคุณ


2
ฉันไม่เห็นว่ามีอะไรผิดปกติกับคำตอบนี้โหวตขึ้นเพราะฉันเห็นการโหวตลดลง
jpemberthy

นี่คือคำตอบที่มีประสิทธิภาพมากที่สุด ( โดยมาก ) ฉันไม่ได้เป็นคนที่มีประสิทธิภาพ แต่สิ่งนี้จะเพิ่มขึ้นจริงๆหากคุณกำลังทำงานกับไฟล์ขนาดใหญ่
ชิป

3

อาจเป็นประโยชน์กับคุณ นี่คือรหัสที่ใช้คลิปหนีบกระดาษและรูปภาพที่มีอยู่ในรีโมต URL

require 'rubygems'
require 'open-uri'
require 'paperclip'
model.update_attribute(:photo,open(website_vehicle.image_url))

ในรุ่น

class Model < ActiveRecord::Base
  has_attached_file :photo, :styles => { :small => "150x150>", :thumb => "75x75>" }
end

3

เนื่องจากเป็นคำตอบเก่านี่เป็นคำตอบที่ใหม่กว่า:

เพิ่ม Image Remote URL ไปยัง Controller ที่คุณต้องการในฐานข้อมูล

$ rails generate migration AddImageRemoteUrlToYour_Controller image_remote_url:string
$ rake db:migrate

แก้ไขโมเดลของคุณ

attr_accessible :description, :image, :image_remote_url
.
.
.
def image_remote_url=(url_value)
  self.image = URI.parse(url_value) unless url_value.blank?
  super
end

* ใน Rails4 คุณต้องเพิ่ม attr_accessible ใน Controller

อัปเดตแบบฟอร์มของคุณหากคุณอนุญาตให้ผู้อื่นอัปโหลดรูปภาพจาก URL

<%= f.input :image_remote_url, label: "Enter a URL" %>

มีไว้superเพื่ออะไร?
Terence Chow

ฟังก์ชันsuperนี้ใช้เพื่อเรียกใช้เมธอดดั้งเดิมการค้นหาเนื้อหาของเมธอดจะเริ่มต้นในซูเปอร์คลาสของอ็อบเจ็กต์ที่พบว่ามีเมธอดดั้งเดิม
มินิจอห์น

2

นี่เป็นวิธีที่ไม่ยอมใครง่ายๆ:

original_url = url.gsub(/\?.*$/, '')
filename = original_url.gsub(/^.*\//, '')
extension = File.extname(filename)

temp_images = Magick::Image.from_blob open(url).read
temp_images[0].write(url = "/tmp/#{Uuid.uuid}#{extension}")

self.file = File.open(url)

โดยที่ Uuid.uuid สร้าง ID แบบสุ่ม


2

รายงานเป็นเอกสารอย่างเป็นทางการที่นี่https://github.com/thoughtbot/paperclip/wiki/Attachment-downloaded-from-a-URL

อย่างไรก็ตามดูเหมือนว่าจะไม่อัปเดตเนื่องจากในคลิปหนีบกระดาษเวอร์ชันล่าสุดมีการเปลี่ยนแปลงและโค้ดบรรทัดนี้ไม่ถูกต้องอีกต่อไป:

user.picture = URI.parse(url)

มันทำให้เกิดข้อผิดพลาดโดยเฉพาะข้อผิดพลาดนี้จะเกิดขึ้น:

Paperclip::AdapterRegistry::NoHandlerError: No handler found for #<URI:: ...

ไวยากรณ์ที่ถูกต้องใหม่คือไวยากรณ์นี้:

url = "https://www.example.com/photo.jpeg"
user.picture = Paperclip.io_adapters.for(URI.parse(url).to_s, { hash_digest: Digest::MD5 })

นอกจากนี้เราต้องเพิ่มบรรทัดเหล่านี้ลงในไฟล์config / initializers / paperclip.rb :

Paperclip::DataUriAdapter.register
Paperclip::HttpUrlProxyAdapter.register

ทดสอบสิ่งนี้กับรุ่นที่หนีบกระดาษ5.3.0และใช้งานได้


ขอบคุณสำหรับสิ่งนี้ - สิ่งที่กำหนดค่าได้รับการแก้ไขให้ฉัน (Paperclip v6.1.0)
Owlvark
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.