Salva l'immagine dall'URL con la graffetta


Risposte:


154

Ecco un modo semplice:

require "open-uri"

class User < ActiveRecord::Base
  has_attached_file :picture

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

Quindi semplicemente:

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

7
Se è necessario utilizzare update_attributesrinomina picture_from_urlin, picture_url=(value)ad esempio.
Daniel Rikowski

3
Questo è potenzialmente insicuro perché un utente potrebbe chiamare user.picture_from_url('/etc/password'). Tuttavia, probabilmente va bene nella maggior parte delle situazioni.
David Tuite

1
Per sicurezza, dovresti inserire nella whitelist lo schema dell'URI e inserire nella lista nera gli host privati
John Douthat

3
Vedi la risposta sotto per una soluzione ancora migliore.
geekazoid

6
Utilizzando open(url), il nome del file non è accurato, ad esempio open-uri20150106-10034-lpd5fm.invece di ef3a601e_ef3d008b_ef3d0f7e.jpg.
Joshua Pinter

196

In Paperclip 3.1.4 è diventato ancora più semplice.

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

Questo è leggermente migliore di open (url). Perché con open (url) otterrai "stringio.txt" come nome del file. Con quanto sopra otterrai un nome corretto del file basato sull'URL. vale a dire

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

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

3
Dal wiki di paperclip: github.com/ Thoughtbot/ paperclip/wiki/… L' ho eseguito con successo nella console, l'app è in heroku.
Donny Kurnia

3
Cordiali saluti, per gli URL S3 ottengo ancora application/octet_streamcome content_type.
Joshua Pinter

5
Se stai ancora utilizzando la graffetta dopo la sua deprecazione, potresti dover assicurarti anche che il caricatore URI IO venga caricato: Paperclip :: UriAdapter.register (nella configurazione, o temporaneamente tramite la console se è tutto ciò di cui hai bisogno)
Msencenb

L'approccio è corretto ma nell'ultima versione la sintassi è cambiata! Controlla la mia risposta di seguito => stackoverflow.com/a/56039191/3182171
Diego D

È necessario aggiungere una voce
nell'inizializzatore

16

Non ha funzionato per me fino a quando non ho usato "open" per l'URI analizzato. una volta aggiunto "open" ha funzionato!

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

La mia versione della graffetta è 4.2.1

Prima di aprirlo non rilevava il tipo di contenuto corretto, perché non era un file. Direbbe image_content_type: "binary / octet-stream", e anche se lo sovrascrivessi con il giusto tipo di contenuto non funzionerebbe.


Grazie per questo! Esattamente quello che mi stavo perdendo.
Dan

Perderai la tua estensione se lo fai. Hai bisogno di Paperclip :: UriAdapter.register nell'inizializzatore .. quindi non hai bisogno di .open alla fine. Vedi github.com/
Thoughtbot

15

Prima scarica l'immagine con la curbgemma su a, TempFilequindi assegna semplicemente l'oggetto tempfile e salva il tuo modello.


2
Non vedo cosa c'è di sbagliato in questa risposta, votandola perché vedo un voto negativo.
jpemberthy

Questa è la risposta più performante ( di gran lunga ). Non sono davvero un fanatico delle prestazioni, ma questo si aggiunge se lavori con file di grandi dimensioni.
Chip

3

Potrebbe esserti utile. Ecco il codice utilizzando graffetta e immagine presente nell'URL remoto.

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

Nel modello

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

3

Poiché quelli sono vecchi, eccone uno più nuovo:

Aggiungi l'URL remoto dell'immagine al controller desiderato nel database

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

Modifica il tuo modello

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

* In Rails4 devi aggiungere attr_accessible nel Controller.

Aggiorna il modulo, se consenti ad altri di caricare un'immagine da un URL

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

a cosa serve super?
Terence Chow

La funzione superviene utilizzata per richiamare il metodo originale, la ricerca del corpo del metodo inizia nella super classe dell'oggetto che è stato trovato per contenere il metodo originale
Mini John

2

Questo è un metodo 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)

dove Uuid.uuid crea solo un ID casuale.


2

Nella documentazione ufficiale è riportato qui https://github.com/ Thoughtbot/ paperclip/ wiki/ Attachment- downloaded- from-a-URL

Comunque sembra non aggiornato, perché nell'ultima versione di paperclip qualcosa è cambiato e questa riga di codice non è più valida:

user.picture = URI.parse(url)

Solleva un errore, in particolare viene sollevato questo errore:

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

La nuova sintassi corretta è questa:

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

Inoltre dobbiamo aggiungere queste righe nel file config / initializers / paperclip.rb :

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

Testato con la versione a graffetta 5.3.0e funziona.


Grazie per questo - le cose di configurazione lo hanno risolto per me (Paperclip v6.1.0)
Owlvark
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.