Bild von der URL per Büroklammer speichern


Antworten:


154

Hier ist ein einfacher Weg:

require "open-uri"

class User < ActiveRecord::Base
  has_attached_file :picture

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

Dann einfach:

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

7
Wenn Sie verwenden müssen update_attributesUmbenennungs picture_from_urlum picture_url=(value)zum Beispiel.
Daniel Rikowski

3
Dies ist möglicherweise unsicher, da ein Benutzer anrufen könnte user.picture_from_url('/etc/password'). In den meisten Situationen ist es wahrscheinlich in Ordnung.
David Tuite

1
Aus Sicherheitsgründen sollten Sie das Schema der URI auf die Whitelist setzen und private Hosts auf die schwarze Liste setzen
John Douthat

3
Siehe Antwort unten für eine noch bessere Lösung.
Geekazoid

6
Bei Verwendung open(url)ist der Dateiname nicht korrekt, z . B. open-uri20150106-10034-lpd5fm.anstelle von ef3a601e_ef3d008b_ef3d0f7e.jpg.
Joshua Pinter

196

In Paperclip 3.1.4 ist es noch einfacher geworden.

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

Dies ist etwas besser als offen (url). Denn mit open (url) erhalten Sie "stringio.txt" als Dateinamen. Mit dem oben genannten erhalten Sie einen richtigen Namen der Datei basierend auf der URL. dh

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

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

3
Aus dem Büroklammer-Wiki: github.com/thoughtbot/paperclip/wiki/… Ich habe es erfolgreich in der Konsole ausgeführt, die App ist in Heroku.
Donny Kurnia

3
Zu Ihrer Information, für S3-URLs bekomme ich immer noch application/octet_streamals content_type.
Joshua Pinter

5
Wenn Sie nach dem Veralten immer noch Büroklammer verwenden, müssen Sie möglicherweise auch sicherstellen, dass der URI IO-Loader geladen wird: Paperclip :: UriAdapter.register (in der Konfiguration oder vorübergehend über die Konsole, wenn dies alles ist, was Sie benötigen)
Msencenb

Der Ansatz ist korrekt, aber in der letzten Version wurde die Sintax geändert! Überprüfen Sie meine Antwort unten => stackoverflow.com/a/56039191/3182171
Diego D

Sie müssen einen Eintrag im Initialisierer hinzufügen github.com/thoughtbot/paperclip/wiki/…
ianpetzer

16

Es hat bei mir nicht funktioniert, bis ich "open" für die analysierte URI verwendet habe. Sobald ich "open" hinzugefügt habe, hat es funktioniert!

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

Meine Büroklammerversion ist 4.2.1

Vor dem Öffnen wurde der Inhaltstyp nicht richtig erkannt, da es sich nicht um eine Datei handelte. Es würde image_content_type sagen: "binary / octet-stream", und selbst wenn ich es mit dem richtigen Inhaltstyp überschreibe, würde es nicht funktionieren.


Danke dafür! Genau das, was ich selbst vermisst habe.
Dan

Sie werden Ihre Ausdehnung verlieren, wenn Sie dies tun. Sie benötigen Paperclip :: UriAdapter.register im Initialisierer. Dann brauchen Sie .open am Ende nicht. Siehe github.com/thoughtbot/paperclip/wiki/…
ianpetzer

15

Laden Sie zuerst das Bild mit dem curbEdelstein auf a herunter TempFileund weisen Sie dann einfach das tempfile-Objekt zu und speichern Sie Ihr Modell.


2
Ich sehe nicht, was mit dieser Antwort falsch ist, stimme ab, weil ich eine Abwertung sehe.
September

Dies ist ( mit Abstand ) die performanteste Antwort . Ich bin nicht wirklich ein Performance-Geek, aber das summiert sich wirklich, wenn Sie mit großen Dateien arbeiten.
Chip

3

Es kann für Sie hilfreich sein. Hier ist der Code mit Büroklammer und Bild in der Remote-URL.

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

Im Modell

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

3

Da dies alte Antworten sind, ist hier eine neuere:

Fügen Sie Ihrem gewünschten Controller in der Datenbank eine Image-Remote-URL hinzu

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

Bearbeiten Sie Ihr Modell

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 müssen Sie attr_accessible im Controller hinzufügen.

Aktualisieren Sie Ihr Formular, wenn Sie anderen erlauben, ein Bild von einer URL hochzuladen

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

Wofür ist das super?
Terence Chow

Die Funktion superwird verwendet, um die ursprüngliche Methode aufzurufen. Die Suche nach dem Methodenkörper beginnt in der Superklasse des Objekts, das die ursprüngliche Methode enthält
Mini John

2

Dies ist eine Hardcore-Methode:

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)

wo Uuid.uuid nur eine zufällige ID macht.


2

In die offizielle Dokumentation wird hier https://github.com/thoughtbot/paperclip/wiki/Attachment-downloaded-from-a-URL berichtet

Auf jeden Fall scheint es nicht aktualisiert zu sein, da sich in der letzten Version der Büroklammer etwas geändert hat und diese Codezeile nicht mehr gültig ist:

user.picture = URI.parse(url)

Es wird ein Fehler ausgelöst, insbesondere wird dieser Fehler ausgelöst:

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

Die neue korrekte Syntax lautet:

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

Außerdem müssen wir diese Zeilen in die Datei config / initializers / paperclip.rb einfügen :

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

Getestet mit Büroklammer Version 5.3.0und es funktioniert.


Vielen Dank dafür - das Konfigurationsmaterial hat es für mich behoben (Paperclip v6.1.0)
Owlvark
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.