allow content entry file field type to access the size of the file + new liquid filter: human_size to format nicely the size of a file for instance
did
committed Feb 18, 2016
commit 0db5573cdf5c44edd279c6ef7aba4b6b2c4084d7
Showing 14
changed files with
139 additions
and 33 deletions
locomotive/steam/adapters/filesystem/yaml_loaders/content_entry.rb b/lib/locomotive/steam/adapters/filesystem/yaml_loaders/content_entry.rb
+22
-0
| @@ | @@ -22,6 +22,7 @@ module Locomotive |
| modify_for_selects(_attributes) | |
| modify_for_associations(_attributes) | |
| + | modify_for_files(_attributes) |
| list << _attributes | |
| end | |
| @@ | @@ -34,6 +35,27 @@ module Locomotive |
| end | |
| end | |
| + | def modify_for_files(attributes) |
| + | content_type.file_fields.each do |field| |
| + | attributes[:"#{field.name}_size"] ||= {} |
| + | value = attributes[:"#{field.name}_size"] |
| + | |
| + | if (path = attributes[field.name.to_sym]).is_a?(Hash) |
| + | path.each { |locale, path| value[locale.to_s] = file_size(path) } |
| + | else |
| + | value['default'] = file_size(path) |
| + | end |
| + | end |
| + | end |
| + | |
| + | def file_size(path) |
| + | return nil if path.blank? |
| + | |
| + | _path = File.join(site_path, 'public', path) |
| + | |
| + | File.exists?(_path) ? File.size(_path) : nil |
| + | end |
| + | |
| def modify_for_associations(attributes) | |
| content_type.association_fields.each do |field| | |
| case field.type | |
locomotive/steam/entities/content_entry.rb b/lib/locomotive/steam/entities/content_entry.rb
+8
-3
| @@ | @@ -129,8 +129,13 @@ module Locomotive::Steam |
| end | |
| def _cast_file(field) | |
| - | _cast_convertor(field.name) do |value| |
| - | value.respond_to?(:url) ? value : FileField.new(value, self.base_url, self.updated_at) |
| + | _cast_convertor(field.name) do |value, locale| |
| + | if value.respond_to?(:url) |
| + | value |
| + | else |
| + | size = (self[:"#{field.name}_size"] || {})[locale || 'default'] |
| + | FileField.new(value, self.base_url, size, self.updated_at) |
| + | end |
| end | |
| end | |
| @@ | @@ -172,7 +177,7 @@ module Locomotive::Steam |
| # Represent a file | |
| class FileField | |
| - | attr_accessor_initialize :filename, :base, :updated_at |
| + | attr_accessor_initialize :filename, :base, :size, :updated_at |
| def url | |
| return if filename.blank? | |
locomotive/steam/entities/content_type.rb b/lib/locomotive/steam/entities/content_type.rb
+1
-0
| @@ | @@ -7,6 +7,7 @@ module Locomotive::Steam |
| def_delegator :fields, :associations, :association_fields | |
| def_delegator :fields, :selects, :select_fields | |
| + | def_delegator :fields, :files, :file_fields |
| def_delegator :fields, :default, :fields_with_default | |
| def initialize(attributes = {}) | |
locomotive/steam/liquid/drops/upload_file.rb b/lib/locomotive/steam/liquid/drops/upload_file.rb
+0
-23
| @@ | @@ -1,23 +0,0 @@ |
| - | module Locomotive |
| - | module Steam |
| - | module Liquid |
| - | module Drops |
| - | class UploadedFile < Base |
| - | |
| - | delegate :size, :filename, to: :@_source |
| - | |
| - | def url |
| - | asset_host.compute(@_source.url, @_source.updated_at.try(:to_i)) |
| - | end |
| - | |
| - | private |
| - | |
| - | def asset_host |
| - | @context.registers[:services].asset_host |
| - | end |
| - | |
| - | end |
| - | end |
| - | end |
| - | end |
| - | end |
locomotive/steam/liquid/drops/uploaded_file.rb b/lib/locomotive/steam/liquid/drops/uploaded_file.rb
+23
-0
| @@ | @@ -0,0 +1,23 @@ |
| + | module Locomotive |
| + | module Steam |
| + | module Liquid |
| + | module Drops |
| + | class UploadedFile < Base |
| + | |
| + | delegate :size, :filename, to: :@_source |
| + | |
| + | def url |
| + | asset_host.compute(@_source.url, @_source.updated_at.try(:to_i)) |
| + | end |
| + | |
| + | private |
| + | |
| + | def asset_host |
| + | @context.registers[:services].asset_host |
| + | end |
| + | |
| + | end |
| + | end |
| + | end |
| + | end |
| + | end |
locomotive/steam/liquid/filters/number.rb b/lib/locomotive/steam/liquid/filters/number.rb
+4
-0
| @@ | @@ -12,6 +12,10 @@ module Locomotive |
| NumberProxyHelper.new(:percentage, @context).invoke(input, options) | |
| end | |
| + | def human_size(input, *options) |
| + | NumberProxyHelper.new(:human_size, @context).invoke(input, options) |
| + | end |
| + | |
| def mod(input, modulus) | |
| input.to_i % modulus.to_i | |
| end | |
locomotive/steam/models/i18n_field.rb b/lib/locomotive/steam/models/i18n_field.rb
+3
-1
| @@ | @@ -43,7 +43,9 @@ module Locomotive::Steam |
| if default | |
| @translations = Hash.new(yield(default)) | |
| else | |
| - | each { |l, _value| self[l] = yield(_value) } |
| + | each do |l, _value| |
| + | self[l] = block.arity == 2 ? yield(_value, l) : yield(_value) |
| + | end |
| end | |
| self | |
| end | |
locomotive/steam/repositories/content_type_field_repository.rb b/lib/locomotive/steam/repositories/content_type_field_repository.rb
+4
-0
| @@ | @@ -22,6 +22,10 @@ module Locomotive |
| query { where(type: :select) }.all | |
| end | |
| + | def files |
| + | query { where(type: :file) }.all |
| + | end |
| + | |
| def belongs_to | |
| query { where(type: :belongs_to) }.all | |
| end | |
spec/fixtures/default/data/songs.yml
+4
-2
| @@ | @@ -8,7 +8,9 @@ |
| duration: "6:28" | |
| short_description: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur vitae tincidunt urna. Nunc felis purus, ultricies et venenatis bibendum, fringilla eu lectus. Sed cursus, sem at blandit mattis, libero quam egestas tortor, eget cursus dolor tellus id nunc. | |
| audio_url: http://blip.tv/file/get/NicolasRaynier-Milk617.flv | |
| - | cover: /samples/asset_collections/cover.jpg |
| + | cover: |
| + | en: /samples/asset_collections/cover.jpg |
| + | fr: /samples/photo_2.jpg |
| band: pearl-jam | |
| - "Song #3": | |
| duration: "6:28" | |
| @@ | @@ -43,4 +45,4 @@ |
| duration: "6:28" | |
| short_description: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur vitae tincidunt urna. Nunc felis purus, ultricies et venenatis bibendum, fringilla eu lectus. Sed cursus, sem at blandit mattis, libero quam egestas tortor, eget cursus dolor tellus id nunc. | |
| audio_url: http://blip.tv/file/get/NicolasRaynier-Milk617.flv | |
| - | cover: /samples/asset_collections/cover.jpg |
| \ No newline at end of file | |
| + | cover: /samples/asset_collections/cover.jpg |
spec/unit/adapters/filesystem/yaml_loaders/content_entry_spec.rb
+19
-3
| @@ | @@ -6,7 +6,7 @@ require_relative '../../../../../lib/locomotive/steam/adapters/filesystem/yaml_l |
| describe Locomotive::Steam::Adapters::Filesystem::YAMLLoaders::ContentEntry do | |
| let(:site_path) { default_fixture_site_path } | |
| - | let(:content_type) { instance_double('Bands', _id: 42, slug: 'bands', association_fields: [], select_fields: []) } |
| + | let(:content_type) { instance_double('Bands', _id: 42, slug: 'bands', association_fields: [], select_fields: [], file_fields: []) } |
| let(:scope) { instance_double('Scope', locale: :en, context: { content_type: content_type }) } | |
| let(:loader) { described_class.new(site_path) } | |
| @@ | @@ -23,7 +23,7 @@ describe Locomotive::Steam::Adapters::Filesystem::YAMLLoaders::ContentEntry do |
| context 'a content type with a belongs_to field' do | |
| let(:field) { instance_double('Field', name: 'band', type: :belongs_to) } | |
| - | let(:content_type) { instance_double('Songs', slug: 'songs', association_fields: [field], select_fields: []) } |
| + | let(:content_type) { instance_double('Songs', slug: 'songs', association_fields: [field], select_fields: [], file_fields: []) } |
| it 'adds a new attribute for the foreign key' do | |
| expect(subject.first[:band_id]).to eq 'pearl-jam' | |
| @@ | @@ -36,7 +36,7 @@ describe Locomotive::Steam::Adapters::Filesystem::YAMLLoaders::ContentEntry do |
| context 'a content type with a select field' do | |
| let(:field) { instance_double('Field', name: 'kind', type: :select) } | |
| - | let(:content_type) { instance_double('Bands', slug: 'bands', select_fields: [field], association_fields: []) } |
| + | let(:content_type) { instance_double('Bands', slug: 'bands', select_fields: [field], association_fields: [], file_fields: []) } |
| it 'adds a new attribute for the foreign key' do | |
| expect(subject.first[:kind_id]).to eq 'grunge' | |
| @@ | @@ -45,6 +45,22 @@ describe Locomotive::Steam::Adapters::Filesystem::YAMLLoaders::ContentEntry do |
| end | |
| + | context 'a content type with a file field' do |
| + | |
| + | let(:field) { instance_double('Field', name: 'cover', type: :file) } |
| + | let(:content_type) { instance_double('Songs', slug: 'songs', select_fields: [], association_fields: [], file_fields: [field]) } |
| + | |
| + | it 'stores the size of the file' do |
| + | expect(subject.first[:cover_size]).to eq('default' => 14768) |
| + | end |
| + | |
| + | it 'stores the size of the file in multiple locales' do |
| + | expect(subject[1][:cover_size]).to eq('en' => 14768, 'fr' => 165883) |
| + | end |
| + | |
| + | |
| + | end |
| + | |
| end | |
| end | |
spec/unit/entities/content_entry_spec.rb
+9
-0
| @@ | @@ -169,11 +169,20 @@ describe Locomotive::Steam::ContentEntry do |
| context 'a file' do | |
| let(:field_type) { :file } | |
| let(:value) { '/foo.png' } | |
| + | let(:attributes) { { my_field: value, my_field_size: { 'default' => 42 } } } |
| it { expect(subject.url).to eq('/foo.png') } | |
| + | it { expect(subject.size).to eq(42) } |
| context 'localized' do | |
| let(:value) { build_i18n_field(en: '/foo-en.png', fr: '/foo-fr.png') } | |
| + | let(:attributes) { { my_field: value, my_field_size: { 'en' => 42, 'fr' => 7 } } } |
| it { expect(subject.translations[:en].url).to eq('/foo-en.png') } | |
| + | it { expect(subject.translations[:en].size).to eq(42) } |
| it { expect(subject.translations[:fr].url).to eq('/foo-fr.png') } | |
| + | it { expect(subject.translations[:fr].size).to eq(7) } |
| + | end |
| + | context 'no file size provided' do |
| + | let(:attributes) { { my_field: value } } |
| + | it { expect(subject.size).to eq(nil) } |
| end | |
| end | |
spec/unit/liquid/drops/content_entry_spec.rb
+1
-1
| @@ | @@ -101,7 +101,7 @@ describe Locomotive::Steam::Liquid::Drops::ContentEntry do |
| describe '#as_json' do | |
| let(:type) { instance_double('Type', fields_by_name: { title: instance_double('StringField', type: :string ), picture: instance_double('FileField', type: :file), category: instance_double('SelectField', type: :select) }) } | |
| - | let(:picture_field) { Locomotive::Steam::ContentEntry::FileField.new('foo.png', 'http://assets.dev', 42) } |
| + | let(:picture_field) { Locomotive::Steam::ContentEntry::FileField.new('foo.png', 'http://assets.dev', 0, 42) } |
| before do | |
| allow(entry).to receive(:to_hash).and_return({ '_id' => 1, 'title' => 'Hello world', 'picture' => picture_field, 'category_id' => 42 }) | |
spec/unit/liquid/filters/number_spec.rb
+29
-0
| @@ | @@ -87,6 +87,35 @@ describe Locomotive::Steam::Liquid::Filters::Number do |
| end | |
| + | describe '#human_size' do |
| + | |
| + | subject { human_size(input, options) } |
| + | |
| + | context 'not a number' do |
| + | |
| + | it { expect(subject).to eq nil } |
| + | |
| + | end |
| + | |
| + | context 'a number' do |
| + | |
| + | let(:input) { 1234567890 } |
| + | |
| + | it { expect(subject).to eq '1.15 GB' } |
| + | |
| + | end |
| + | |
| + | context 'with options' do |
| + | |
| + | let(:input) { '1234567' } |
| + | let(:options) { ['precision: 2'] } |
| + | |
| + | it { expect(subject).to eq '1.2 MB' } |
| + | |
| + | end |
| + | |
| + | end |
| + | |
| describe '#mod' do | |
| it 'returns correct number modulus' do | |
spec/unit/repositories/content_type_field_repository_spec.rb
+12
-0
| @@ | @@ -55,6 +55,18 @@ describe Locomotive::Steam::ContentTypeFieldRepository do |
| subject { repository.default } | |
| it { expect(subject.first.name).to eq 'email' } | |
| + | it { expect(subject.count).to eq 1 } |
| + | |
| + | end |
| + | |
| + | describe '#files' do |
| + | |
| + | let(:collection) { [{ name: 'name', type: 'string' }, { name: 'picture', type: 'file' }] } |
| + | |
| + | subject { repository.files } |
| + | |
| + | it { expect(subject.first.name).to eq 'picture' } |
| + | it { expect(subject.count).to eq 1 } |
| end | |