Simpan gambar dari URL dengan penjepit kertas

Jawaban:

154

Ini caranya yang sederhana:

require "open-uri"

class User < ActiveRecord::Base
  has_attached_file :picture

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

Kemudian cukup:

user.picture_from_url "http://www.google.com/images/logos/ps_logo2.png"
Nicolas Blanco
sumber
7
Jika Anda perlu menggunakan update_attributesganti nama picture_from_urlmenjadi picture_url=(value)misalnya.
Daniel Rikowski
3
Ini berpotensi tidak aman karena pengguna dapat menelepon user.picture_from_url('/etc/password'). Mungkin baik-baik saja dalam kebanyakan situasi.
David Tuite
1
Untuk keamanan, Anda harus memasukkan skema URI ke daftar putih dan host pribadi daftar hitam
John Douthat
3
Lihat jawaban di bawah untuk solusi yang lebih baik.
geekazoid
6
Menggunakan open(url), nama file tidak akurat, misalnya, open-uri20150106-10034-lpd5fm.bukan ef3a601e_ef3d008b_ef3d0f7e.jpg.
Joshua Pinter
196

Di Paperclip 3.1.4 ini menjadi lebih sederhana.

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

Ini sedikit lebih baik daripada buka (url). Karena dengan open (url) Anda akan mendapatkan "stringio.txt" sebagai nama filenya. Dengan cara di atas Anda akan mendapatkan nama file yang tepat berdasarkan URL. yaitu

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

self.picture_file_name    # => "avatar.png"
self.picture_content_type # => "image/png"
Aditya Sanghi
sumber
3
Dari wiki penjepit kertas: github.com/thoughtbot/paperclip/wiki/… Saya berhasil menjalankannya di konsol, aplikasinya ada di heroku.
Donny Kurnia
3
FYI, untuk url S3 saya masih dapat application/octet_stream sebagai content_type.
Joshua Pinter
5
Jika Anda masih menggunakan penjepit kertas setelah tidak digunakan lagi, Anda mungkin juga perlu memastikan pemuat URI IO dimuat: Paperclip :: UriAdapter.register (dalam konfigurasi, atau untuk sementara melalui konsol jika hanya itu yang Anda butuhkan)
Msencenb
Pendekatannya benar tetapi di versi terakhir sintax diubah! Lihat jawaban saya di bawah ini => stackoverflow.com/a/56039191/3182171
Diego D
Anda perlu menambahkan entri di penginisialisasi github.com/thoughtbot/paperclip/wiki/…
ianpetzer
16

Ini tidak berhasil untuk saya sampai saya menggunakan "buka" untuk URI yang diuraikan. setelah saya menambahkan "buka", itu berhasil!

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

Versi penjepit kertas saya adalah 4.2.1

Sebelum dibuka itu tidak akan mendeteksi jenis konten dengan benar, karena itu bukan file. Ini akan mengatakan image_content_type: "binary / octet-stream", dan bahkan jika saya menimpanya dengan tipe konten yang tepat itu tidak akan berhasil.

Mïchael Makaröv
sumber
Terima kasih untuk ini! Persis apa yang saya rindukan sendiri.
Dan
Anda akan kehilangan ketegangan jika melakukan ini. Anda membutuhkan Paperclip :: UriAdapter.register di penginisialisasi .. maka Anda tidak perlu .open di akhir. Lihat github.com/thoughtbot/paperclip/wiki/…
ianpetzer
15

Pertama unduh gambar dengan curbpermata ke a TempFiledan kemudian cukup tetapkan objek tempfile dan simpan model Anda.

Ariejan
sumber
2
Saya tidak melihat apa yang salah dengan jawaban ini, memilihnya karena saya melihat penurunan suara.
jpemberthy
Ini adalah jawaban yang paling berhasil ( sejauh ini ). Saya bukan seorang ahli kinerja, tetapi ini benar-benar bertambah jika Anda bekerja dengan file besar.
Chip
3

Mungkin membantu Anda. Berikut adalah kode menggunakan penjepit kertas dan gambar yang ada di URL jarak jauh.

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

Dalam model

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

Karena itu adalah Jawaban lama, inilah yang lebih baru:

Tambahkan Image Remote URL ke Controller yang Anda inginkan dalam Database

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

Edit Model Anda

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

* Di Rails4 Anda harus menambahkan attr_accessible di Controller.

Perbarui formulir Anda, jika Anda mengizinkan orang lain untuk mengunggah Gambar dari URL

<%= f.input :image_remote_url, label: "Enter a URL" %>
Mini John
sumber
apa superuntuk?
Terence Chow
Fungsi superini digunakan untuk memanggil metode asli, pencarian metode tubuh dimulai di kelas super dari objek yang ditemukan mengandung metode asli
Mini John
2

Ini adalah metode hardcore:

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)

dimana Uuid.uuid hanya membuat beberapa ID acak.

Martin Streicher
sumber
2

Ke dalam dokumentasi resmi dilaporkan di sini https://github.com/thoughtbot/paperclip/wiki/Attachment-downloaded-from-a-URL

Pokoknya sepertinya tidak diperbarui, karena pada versi terakhir penjepit kertas ada yang berubah dan baris kode ini tidak lagi valid:

user.picture = URI.parse(url)

Ini menimbulkan kesalahan, khususnya kesalahan ini dimunculkan:

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

Sintaks baru yang benar adalah yang ini:

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

Juga kita perlu menambahkan baris ini ke file config / initializers / paperclip.rb :

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

Menguji ini dengan versi penjepit kertas 5.3.0dan berhasil.

Diego D
sumber
Terima kasih untuk ini - hal-hal konfigurasi memperbaikinya untuk saya (Paperclip v6.1.0)
Owlvark