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.