Метод открытия Ruby open-uri теряет изображения открытия расширения файла

Я использую ruby ​​1.9.2 вместе с Rails 3.1.4 и Paperclip 2.4.5.

Моя проблема заключается в том, что при попытке сохранить вложение скрепки из URI теряется расширение файла и сохраняется файл без него, что приводит к проблемам с такими вещами, как fancybox, для которых требуется расширение.

Некоторый пример кода:

uri = "http://featherfiles.aviary.com/2012-06-13/bbe5f0de1/0c5a672b88ea47ecb4631ac173e27430.png"
open(uri)
#=> #<File:/var/folders/zc/d69gxhzx10x_bvjrkqgyjgxr0000gn/T/open-uri20120613-27204-i6cldv>

Поскольку у временного файла нет расширения, скрепка сохраняет файл без каких-либо проблем.

Кто-нибудь сталкивался с этой проблемой? Я видел несколько ответов об использовании скрепки для хранения изображений из URI, но ни один из них, похоже, не решает ту же проблему, с которой мы работаем.


person Jimmy    schedule 13.06.2012    source источник
comment
Я также сталкиваюсь с этой проблемой.   -  person jfedick    schedule 13.07.2012


Ответы (6)


Не используйте временный файл! Он используется в качестве заполнителя, поскольку файл считывается из порта, и его следует рассматривать как частный ресурс для OpenURI. Вместо этого используйте open(url).read и работайте с полученным контентом, сохраняя его.

Сделайте что-нибудь вроде:

require 'uri'
require 'open-uri'

url = 'http://www.iana.org/domains/example/index.html'
filename = File.basename(URI.parse(url).path)
File.open(filename, 'wb') do |fo|
  fo.write(open(url).read)
end

Временная буферизация на диск во время операции, особенно сетевой операции, является обычным явлением. Как только содержимое файла будет накоплено, его можно будет передать приложению. read блокирует, поэтому ваш код остановится на этом до тех пор, пока вам не вернут файл. Тогда вы можете играть с ним.

person the Tin Man    schedule 12.11.2012

Расширение не важно для временного файла, но если вы хотите использовать этот файл в коде или сохранить в другом месте. Ты можешь это сделать:

temp_file = open(params[:url])
def temp_file.original_filename; File.basename(base_uri.path); end

Теперь вы можете сохранить этот временный файл в постоянном пространстве или использовать его в коде; Исходное имя файла будет использоваться автоматически.

person Sergey Khomushin    schedule 26.01.2016
comment
Не работает. Кажется, необходима некоторая дополнительная магия, чтобы сделать «base_uri» доступным для определенного здесь метода original_filename, к вашему сведению. - person ericpeters0n; 12.11.2016

Я не уверен, поможет ли это в вашем случае, но я замечал подобные проблемы в своем проекте.

Проблема оказалась вызвана не Paperclip и не open-uri, а получателем файла скрепки (в моем случае Spree Commerce). Убедитесь, что вы назначаете объект скрепки правильному объекту и что он интерпретируется правильно.

Исправление, которое сработало для меня, заключалось в изменении:

@product.images << Spree::Image.create({ 
    :attachment => open(image_url) 
}, :without_protection => true)

to

@product.master.images << Spree::Image.create({ 
    :attachment => open(image_url) 
}, :without_protection => true)

Удачи с вашей проблемой

person fatty    schedule 16.06.2012

Вы включили расширение :extension в свой путь/URL-адрес?

Например:

has_attached_file :image,
  ...
  :url  => '/images/highlights/:id_partition/:style_:id.:extension',
  :path => ':rails_root/files/images/highlights/:id_partition/:style_:id.:extension'

Это, вероятно, решит вашу проблему. Вы можете форсировать расширение, но я не думаю, что это рекомендуется.

person Tiago    schedule 07.10.2012

Обновление — Paperclip может сделать это самостоятельно!

Сообщение от Адитьи Санги (большое спасибо!):

current_comments.pictures.create!(file: URI.parse(image_url))

Хотя имейте в виду, что вам все равно нужно обрабатывать ошибки 500, 404 и т. д. (Paperclip может их поднять).

Спасибо: https://mensfeld.pl/2013/12/rails-paperclip-open-uri-downloading-files-from-the-internet-and-saving-them-with-paperclip/

person Magne    schedule 07.07.2017

Да, это проблема, но мы можем обойти это с помощью fancybox.

В теге ссылки (для изображения) добавьте :type => 'image'

- @images.each do |image|
 = link_to image_tag(image.attachment.url),   image.attachment.url, class: "fancybox", type: 'image'

Указав «тип», Fancybox переопределяет тип как изображение

https://groups.google.com/forum/?fromgroups=#!topic/fancybox/QgjquBCLynU

person user1286523    schedule 05.09.2012
comment
на самом деле это не так уж много и добавляет требование к fancybox для отображения изображений - person Jimmy; 06.09.2012