Загрузка скрепки для офисных файлов (docx, pptx) загружается в виде zip файлов?

Я использую следующие для загрузки файлов: Rails 3.2, Paperclip (3.0.4), aws-sdk (1.5.2) и jQuery-File-Upload

Проблема заключается в том, что такие офисные файлы, как (pptx), загружаются как файлы zip, а не файлы pptx. Вот что я вижу в журналах:

Started POST
Processing by AttachmentsController#create as JS
  Parameters: {"files"=>[#<ActionDispatch::Http::UploadedFile:0x007fa1d5bee960 @original_filename="test1.pptx", @content_type="application/vnd.openxmlformats-officedocument.presentationml.presentation", @headers="Content-Disposition: form-data; name=\"files[]\"; filename=\"test1.pptx\"\r\nContent-Type: application/vnd.openxmlformats-officedocument.presentationml.presentation\r\n", @tempfile=#<File:/var/folders/rm/89l_3yt93g31p22738hqydmr0000gn/T/RackMultipart20120529-10443-1ljhigq>>]}
.....


SQL (1.4ms)  INSERT INTO "attachments" ("attachment_content_type", "attachment_file_name", "attachment_file_size", "attachment_file_title", "attachment_updated_at", "created_at", "deleted", "room_id", "pinned", "updated_at", "user_id") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) RETURNING "id"  [["attachment_content_type", "application/zip"], ["attachment_file_name", "test1_1338339249.pptx"], ["attachment_file_size", 150329], ["attachment_file_title", "test1.pptx"], ["attachment_updated_at", Wed, 30 May 2012 00:54:09 UTC +00:00], ["created_at", Wed, 30 May 2012 00:54:09 UTC +00:00], ["deleted", false], ["room_id", 20], ["pinned", false], ["updated_at", Wed, 30 May 2012 00:54:09 UTC +00:00], ["user_id", 1]]
[paperclip] Saving attachments.
[paperclip] saving /development/private/rooms/20/user_uploaded_files/test1_1338339249.pptx
Command :: file -b --mime '/var/folders/rm/89l_3yt93g31p22738hqydmr0000gn/T/RackMultipart20120529-10443-1ljhigq20120529-10443-1lr2yg2'
[AWS S3 200 1.16513 0 retries] put_object(:acl=>:private,:bucket_name=>"cdn-assets-site-com",:content_type=>"application/zip",:data=>#<Paperclip::FileAdapter:0x007fa1d2540170 @target=#<File:/var/folders/rm/89l_3yt93g31p22738hqydmr0000gn/T/RackMultipart20120529-10443-1ljhigq>, @tempfile=#<File:/var/folders/rm/89l_3yt93g31p22738hqydmr0000gn/T/RackMultipart20120529-10443-1ljhigq20120529-10443-1lr2yg2>>,:key=>"development/private/rooms/20/user_uploaded_files/test1_1338339249.pptx") 

Обратите внимание, что файл входит в pptx, но при загрузке в AWS S3 идет как zip файл?

Ответ 1

Оказывается, как намекнул Марк Б, - все документы Office, заканчивающиеся на x, действительно являются зашифрованными файлами XML. Все, что использует обычные mimetypes, будет предполагать, что это заархивированный файл.

Чтобы обойти это, вы должны зарегистрировать типу Microsoft Office на своем сервере. Итак, для ваших файлов .pptx вы помещаете

Mime::Type.register "application/vnd.openxmlformats-officedocument.presentationml.presentation", :pptx

в файле config/initializers/mime_types.rb.

В качестве альтернативы вы можете использовать метод Rack::Mime::MIME_TYPES.merge!(), который отображается в действии в fooobar.com/questions/448439/..., если вам нужно поддерживать все файлы Office 2007.

Ответ 2

Похоже, что у вас нет зарегистрированных типов MIME.

Файлы Office, заканчивающиеся на x (Office 2007+), действительно являются файлами zipped XML. Все, что использует обычные типы MIME, будет считать его зашифрованным.

Типы MIME для файлов Office 2007+

| File |                             MIME type                                   |
+------+-------------------------------------------------------------------------+
|.docx |application/vnd.openxmlformats-officedocument.wordprocessingml.document  |
+------+-------------------------------------------------------------------------+
|.xlsx |application/vnd.openxmlformats-officedocument.spreadsheetml.sheet        |
+------+-------------------------------------------------------------------------+
|.pptx |application/vnd.openxmlformats-officedocument.presentationml.presentation|

В вашем файле config/initializers/mime_types.rb добавьте требуемое поле, например, пример ниже;

"application/vnd.openxmlformats-officedocument.presentationml.presentation", :pptx

По иронии судьбы IE может испытывать трудности с распознаванием новых файлов MS Office, в то время как другие браузеры прекрасно их распознают.

Чтобы IE работал с этими файлами, вам нужно добавить типы mime в конфигурацию сервера. В Rails это делается в config/initializers/mime_types.rb

Mime::Type.register "application/vnd.openxmlformats-officedocument.wordprocessingml.document", :docx
Mime::Type.register "application/vnd.openxmlformats-officedocument.presentationml.presentation", :pptx
Mime::Type.register "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", :xlsx

Если ваше приложение проксировано через Apache, а Apache обслуживает ваши статические активы, вам также придется настроить apache с новыми типами mime (и перезапустить) согласно http://bignosebird.com/apache/a1.shtml

Обычно типы mime располагались в /etc/mime.types, но попробуйте locate mime.types, если вы не уверены.

Вы можете ссылаться на адаптеры скрепки.

Вы можете прочитать Описание настроек по умолчанию для свойства MimeMap и свойства ScriptMaps в IIS, Типы MIME для Office 2007 для Apache, Загрузка файлов docx с помощью папок и рельсов и Документы Dynamic Word (.docx) в Rails.

Ответ 3

"x" версии форматов Office ARE zip files - zipped xml. Таким образом, все, что определяет расширения файлов на основе mime-типов, всегда будет рассматривать их как zip файлы.

Ответ 4

Часть Command :: file -b --mime '/var/folders ... вашего журнала означает, что Paperclip не обнаруживает тип mime с помощью MIME::Types.type_for и возвращается к команде file.

Соответствующий код здесь: https://github.com/thoughtbot/paperclip/blob/5bf0619fe79ffbcaf8f0d8a7aca88b5685aec4b3/lib/paperclip/io_adapters/file_adapter.rb#L16

и здесь: https://github.com/thoughtbot/paperclip/blob/5bf0619fe79ffbcaf8f0d8a7aca88b5685aec4b3/lib/paperclip/io_adapters/file_adapter.rb#L71

Команда file запускается в временном файле без расширения и отображает его ZIP файл, поскольку, как указали другие, это действительно так.

Тот факт, что MIME::Types.type_for("test1.pptx") работает корректно для вас в консоли, кажется, указывает, что либо original_filename является странным в той части кода, либо MIME::Types.type_for ведет себя по-другому в папке, чем в вашей консоли.

Можете ли вы измерить соответствующую часть драгоценного камня (через отладчик или выбросить некоторые отпечатки в своей локальной копии), чтобы увидеть, что он видит? Кроме того, можете ли вы предоставить более подробную информацию о том, как вы конвертируете параметры, которые ваш контроллер получает в объекты привязки?

Ответ 5

Для тех, кто считает, что это все еще не работает, более новые версии Paperclip имеют зависимость mimemagic от gem в Paperclip::ContentTypeDetector. Вы захотите зарегистрировать типы mime с этим.