Збережіть зображення з URL за допомогою скріпки


Відповіді:


154

Ось простий спосіб:

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"

7
Якщо вам потрібно використовувати update_attributesперейменувати picture_from_urlв picture_url=(value), наприклад.
Даніель Ріковський

3
Це потенційно небезпечно, оскільки користувач може зателефонувати user.picture_from_url('/etc/password'). Мабуть, це добре в більшості ситуацій.
Девід Туйте

1
Для безпеки вам слід додати білий список схеми URI та чорний список приватних хостів
Джон Даут,

3
Дивіться відповідь нижче для ще кращого рішення.
geekazoid

6
Використовуючи open(url), ім'я файлу не точно, наприклад, open-uri20150106-10034-lpd5fm.замість ef3a601e_ef3d008b_ef3d0f7e.jpg.
Джошуа Пінтер

196

У скріпці 3.1.4 це стає ще простіше.

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

Це трохи краще, ніж відкритий (URL). Тому що з відкритим (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"

3
З wiki скріпки: github.com/thoughtbot/paperclip/wiki/… Я успішно запускаю його в консолі, додаток - у героїці.
Донні Курня

3
FYI, для URL-адрес S3 я все ще отримую application/octet_streamяк content_type.
Джошуа Пінтер

5
Якщо ви все ще користуєтеся скріпкою паперу після її припинення, вам може знадобитися також завантажувати завантажувач URI IO: Paperclip :: UriAdapter.register (у конфігурації або тимчасово через консоль, якщо це все, що вам потрібно)
Msencenb

Підхід правильний, але в останній версії синтакс змінено! Перевірте мою відповідь нижче => stackoverflow.com/a/56039191/3182171
Дієго D

Вам потрібно додати запис у ініціалізатор github.com/thoughtbot/paperclip/wiki/…
ianpetzer

16

Це не спрацювало для мене, поки я не використав "відкритий" для розбору URI. як тільки я додав "відкрити", це спрацювало!

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

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

Перед відкриттям він не визначив правильний тип вмісту, оскільки це був не файл. Він би сказав image_content_type: "бінарний / октет-потік", і навіть якщо я перекрию його правильним типом вмісту, він не працюватиме.


Дякую за це! Саме те, чого мені бракувало.
Дан

Ви втратите своє переживання, якщо це зробите. Вам потрібен Paperclip :: UriAdapter.register в ініціалізаторі .. тоді вам не знадобиться .open в кінці. Дивіться github.com/thoughtbot/paperclip/wiki/…
ianpetzer

15

Спочатку завантажте зображення з curbдорогоцінним каменем на a, TempFileа потім просто призначте об’єкт tempfile і збережіть свою модель.


2
Я не бачу, що не так у цій відповіді, проголосувавши її, тому що я бачу голос проти.
jpemberthy

Це найефективніша відповідь ( на сьогоднішній день ). Я насправді не є видовищним виконавцем, але це дійсно додається, якщо ви працюєте з великими файлами.
Чіп

3

Це може вам допомогти. Ось код за допомогою скріпки та зображення, присутні у віддаленій 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

3

Оскільки це старий відповідь, ось новий:

Додайте віддалену 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 в Controller.

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

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

для чого це super?
Теренс Чоу

Функція superвикористовується для виклику оригінального методу, пошук тіла методу починається у суперкласі об'єкта, який, як було встановлено, містить оригінальний метод
Mini John

2

Це жорсткий метод:

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 просто робить якийсь випадковий ідентифікатор.


2

До офіційної документації повідомляється тут https://github.com/thoughtbot/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 / inicijalizer / paperclip.rb :

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

Випробували це за допомогою скріпки, 5.3.0і це працює.


Дякую за це - конфігураційні речі виправили це для мене (Paperclip v6.1.0)
Owlvark
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.