Сохранить изображение из URL-адреса скрепкой

Пожалуйста, предложите мне способ сохранить изображение с URL-адреса с помощью скрепки.


person khanh    schedule 29.10.2010    source источник


Ответы (8)


Вот простой способ:

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"
person Nicolas Blanco    schedule 29.10.2010
comment
Если вам нужно использовать update_attributes, переименуйте picture_from_url в picture_url=(value). - person Daniel Rikowski; 02.06.2013
comment
Это потенциально небезопасно, потому что пользователь может вызвать user.picture_from_url('/etc/password'). Хотя, вероятно, в большинстве ситуаций это нормально. - person David Tuite; 11.10.2013
comment
В целях безопасности вы должны занести схему URI в белый список, а частные хосты - в черный. - person John Douthat; 07.01.2014
comment
См. Ответ ниже, чтобы найти еще лучшее решение. - person geekazoid; 03.12.2014
comment
При использовании open(url) имя файла не является точным, например open-uri20150106-10034-lpd5fm. вместо ef3a601e_ef3d008b_ef3d0f7e.jpg. - person Joshua Pinter; 06.01.2015
comment
@joshuaPinter использует URI.parse(url) вместо open(url) - person Simon Franzen; 23.01.2019

В Paperclip 3.1.4 это стало еще проще.

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

Это немного лучше, чем open (url). Потому что с open (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"
person Aditya Sanghi    schedule 20.07.2012
comment
Из вики по скрепке: github.com/gotitbot/paperclip/wiki/ Я успешно запустил его в консоли, приложение находится в героку. - person Donny Kurnia; 18.01.2013
comment
К вашему сведению, для URL-адресов S3 я все еще получаю application/octet_stream как content_type. - person Joshua Pinter; 06.01.2015
comment
Если вы все еще используете скрепку после того, как она устарела, вам может потребоваться также убедиться, что загрузчик ввода-вывода URI загружается: Paperclip :: UriAdapter.register (в конфигурации или временно через консоль, если это все, что вам нужно) - person Msencenb; 09.11.2018
comment
Подход правильный, но в последней версии изменен синтаксис! Посмотрите мой ответ ниже = ›stackoverflow.com/a/56039191/3182171 - person Diego D; 08.05.2019
comment
Вам необходимо добавить запись в инициализатор github.com/gotitbot/paperclip / wiki / - person ianpetzer; 20.08.2019

У меня это не сработало, пока я не использовал "open" для разобранного URI. как только я добавил "открыть", все заработало!

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

Моя версия скрепки - 4.2.1

Перед открытием он не мог правильно определить тип содержимого, потому что это не был файл. Он сказал бы image_content_type: "binary / octet-stream", и даже если бы я заменил его правильным типом содержимого, это не сработало бы.

person Mïchael Makaröv    schedule 21.05.2015
comment
Спасибо за это! Именно то, чего мне не хватало. - person Dan; 05.08.2019
comment
Если вы сделаете это, вы потеряете свое расширение. Вам нужен Paperclip :: UriAdapter.register в инициализаторе ... тогда вам не нужно .open в конце. См. github.com/gotitbot/paperclip/wiki/ - person ianpetzer; 20.08.2019

Сначала загрузите изображение с гемом curb в TempFile, а затем просто назначьте объект временного файла и сохраните свою модель.

person Ariejan    schedule 29.10.2010
comment
Я не вижу, что не так с этим ответом, голосую за него, потому что я вижу голосование против. - person jpemberthy; 11.08.2011
comment
Это наиболее эффективный ответ (безусловно). На самом деле я не фанат производительности, но это действительно складывается, если вы работаете с большими файлами. - person Chip; 24.09.2013

В официальной документации сообщается здесь https://github.com/gotitbot/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, и она работает.

person Diego D    schedule 08.05.2019
comment
Спасибо за это - конфигурация исправила это для меня (Paperclip v6.1.0) - person Owlvark; 19.08.2019
comment
Спасибо, Диего, это тоже хорошо работает, PaperClip v6.0.0 - person Astm; 13.12.2020

Это может быть вам полезно. Вот код с использованием скрепки и изображения в удаленном 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
person prabu    schedule 21.05.2011

Поскольку это старый ответ, вот новый:

Добавьте URL-адрес удаленного изображения к желаемому контроллеру в базе данных

$ 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 в Контроллер.

Обновите форму, если вы разрешаете другим пользователям загружать изображение с URL-адреса

<%= f.input :image_remote_url, label: "Enter a URL" %>
person Mini John    schedule 26.08.2013
comment
для чего super? - person Terence Chow; 26.08.2014
comment
Функция super используется для вызова исходного метода, поиск тела метода начинается в суперклассе объекта, который, как было обнаружено, содержит исходный метод. - person Mini John; 27.08.2014

Это хардкорный метод:

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 просто создает случайный идентификатор.

person Martin Streicher    schedule 06.04.2011