* Fixes #1985 - add migration AddMediaAttachmentMeta, which add meta field to media_attachments - before saving attachment, set file meta if needed - add meta in api * add spec * align the “size” format for image and video * fix code climate * fixes media_attachment_spec.rbmaster
@@ -51,6 +51,7 @@ class MediaAttachment < ApplicationRecord | |||||
before_create :set_shortcode | before_create :set_shortcode | ||||
before_post_process :set_type_and_extension | before_post_process :set_type_and_extension | ||||
before_save :set_meta | |||||
class << self | class << self | ||||
private | private | ||||
@@ -112,6 +113,30 @@ class MediaAttachment < ApplicationRecord | |||||
file.instance_write :file_name, [basename, extension].delete_if(&:empty?).join('.') | file.instance_write :file_name, [basename, extension].delete_if(&:empty?).join('.') | ||||
end | end | ||||
def set_meta | |||||
meta = populate_meta | |||||
return if meta == {} | |||||
file.instance_write :meta, meta | |||||
end | |||||
def populate_meta | |||||
meta = {} | |||||
file.queued_for_write.each do |style, file| | |||||
begin | |||||
geo = Paperclip::Geometry.from_file file | |||||
meta[style] = { | |||||
width: geo.width.to_i, | |||||
height: geo.height.to_i, | |||||
size: "#{geo.width.to_i}x#{geo.height.to_i}", | |||||
aspect: geo.width.to_f / geo.height.to_f, | |||||
} | |||||
rescue Paperclip::Errors::NotIdentifiedByImageMagickError | |||||
meta[style] = {} | |||||
end | |||||
end | |||||
meta | |||||
end | |||||
def appropriate_extension | def appropriate_extension | ||||
mime_type = MIME::Types[file.content_type] | mime_type = MIME::Types[file.content_type] | ||||
@@ -3,3 +3,4 @@ attributes :id, :remote_url, :type | |||||
node(:url) { |media| full_asset_url(media.file.url(:original)) } | node(:url) { |media| full_asset_url(media.file.url(:original)) } | ||||
node(:preview_url) { |media| full_asset_url(media.file.url(:small)) } | node(:preview_url) { |media| full_asset_url(media.file.url(:small)) } | ||||
node(:text_url) { |media| media.local? ? medium_url(media) : nil } | node(:text_url) { |media| media.local? ? medium_url(media) : nil } | ||||
node(:meta) { |media| media.file.meta } |
@@ -0,0 +1,5 @@ | |||||
class AddMediaAttachmentMeta < ActiveRecord::Migration[5.0] | |||||
def change | |||||
add_column :media_attachments, :file_meta, :json | |||||
end | |||||
end |
@@ -10,7 +10,7 @@ | |||||
# | # | ||||
# It's strongly recommended that you check this file into your version control system. | # It's strongly recommended that you check this file into your version control system. | ||||
ActiveRecord::Schema.define(version: 20170424112722) do | |||||
ActiveRecord::Schema.define(version: 20170425131920) do | |||||
# These are extensions that must be enabled in order to support this database | # These are extensions that must be enabled in order to support this database | ||||
enable_extension "plpgsql" | enable_extension "plpgsql" | ||||
@@ -120,6 +120,7 @@ ActiveRecord::Schema.define(version: 20170424112722) do | |||||
t.datetime "updated_at", null: false | t.datetime "updated_at", null: false | ||||
t.string "shortcode" | t.string "shortcode" | ||||
t.integer "type", default: 0, null: false | t.integer "type", default: 0, null: false | ||||
t.json "file_meta" | |||||
t.index ["shortcode"], name: "index_media_attachments_on_shortcode", unique: true, using: :btree | t.index ["shortcode"], name: "index_media_attachments_on_shortcode", unique: true, using: :btree | ||||
t.index ["status_id"], name: "index_media_attachments_on_status_id", using: :btree | t.index ["status_id"], name: "index_media_attachments_on_status_id", using: :btree | ||||
end | end | ||||
@@ -332,4 +333,4 @@ ActiveRecord::Schema.define(version: 20170424112722) do | |||||
end | end | ||||
add_foreign_key "statuses", "statuses", column: "reblog_of_id", on_delete: :cascade | add_foreign_key "statuses", "statuses", column: "reblog_of_id", on_delete: :cascade | ||||
end | |||||
end |
@@ -11,6 +11,13 @@ RSpec.describe MediaAttachment, type: :model do | |||||
it 'converts original file to mp4' do | it 'converts original file to mp4' do | ||||
expect(media.file_content_type).to eq 'video/mp4' | expect(media.file_content_type).to eq 'video/mp4' | ||||
end | end | ||||
it 'sets meta' do | |||||
expect(media.file.meta["original"]["width"]).to eq 128 | |||||
expect(media.file.meta["original"]["height"]).to eq 128 | |||||
expect(media.file.meta["original"]["aspect"]).to eq 1.0 | |||||
end | |||||
end | end | ||||
describe 'non-animated gif non-conversion' do | describe 'non-animated gif non-conversion' do | ||||
@@ -23,5 +30,24 @@ RSpec.describe MediaAttachment, type: :model do | |||||
it 'leaves original file as-is' do | it 'leaves original file as-is' do | ||||
expect(media.file_content_type).to eq 'image/gif' | expect(media.file_content_type).to eq 'image/gif' | ||||
end | end | ||||
it 'sets meta' do | |||||
expect(media.file.meta["original"]["width"]).to eq 600 | |||||
expect(media.file.meta["original"]["height"]).to eq 400 | |||||
expect(media.file.meta["original"]["aspect"]).to eq 1.5 | |||||
end | |||||
end | |||||
describe 'jpeg' do | |||||
let(:media) { MediaAttachment.create(account: Fabricate(:account), file: attachment_fixture('attachment.jpg')) } | |||||
it 'sets meta for different style' do | |||||
expect(media.file.meta["original"]["width"]).to eq 600 | |||||
expect(media.file.meta["original"]["height"]).to eq 400 | |||||
expect(media.file.meta["original"]["aspect"]).to eq 1.5 | |||||
expect(media.file.meta["small"]["width"]).to eq 400 | |||||
expect(media.file.meta["small"]["height"]).to eq 267 | |||||
expect(media.file.meta["small"]["aspect"]).to eq 400.0/267 | |||||
end | |||||
end | end | ||||
end | end |