no need to use carrierwave: Steam takes care of the urls of assets uploaded with Carrierwave (MongoDB adapter), close #31 + little optimizations around the mapper object

did committed Mar 16, 2015
commit 10217d124130e7de67cc150e6be0932f56212c83
Showing 17 changed files with 102 additions and 40 deletions
locomotive/steam/adapters/filesystem.rb b/lib/locomotive/steam/adapters/filesystem.rb +1 -1
@@ @@ -46,7 +46,7 @@ module Locomotive::Steam
_query(mapper, scope) { where(_id: id) }.first
end
- def theme_assets_base_url(scope)
+ def base_url(mapper, scope, entity = nil)
''
end
locomotive/steam/adapters/memory.rb b/lib/locomotive/steam/adapters/memory.rb +4 -0
@@ @@ -22,6 +22,10 @@ module Locomotive::Steam
_query(mapper, scope) { where(_id: id) }.first
end
+ def base_url(mapper, scope, entity = nil)
+ ''
+ end
+
private
def _query(mapper, scope, &block)
locomotive/steam/adapters/mongodb.rb b/lib/locomotive/steam/adapters/mongodb.rb +11 -2
@@ @@ -22,8 +22,17 @@ module Locomotive::Steam
name.__send__(operator)
end
- def theme_assets_base_url(scope)
- ['', 'sites', scope.site._id.to_s, 'theme'].join('/')
+ def base_url(mapper, scope, entity = nil)
+ return nil if scope.site.nil?
+
+ # Note: mimic Carrierwave behaviour
+ base = "/sites/#{scope.site._id.to_s}"
+
+ case mapper.name
+ when :theme_assets then "#{base}/theme"
+ when :pages then "#{base}/pages/#{entity._id}/files"
+ when :content_entries then "#{base}/content_entry#{scope.context[:content_type]._id}/#{entity._id}/files"
+ end
end
private
locomotive/steam/entities/content_entry.rb b/lib/locomotive/steam/entities/content_entry.rb +14 -1
@@ @@ -96,7 +96,7 @@ module Locomotive::Steam
def _cast_file(field)
_cast_convertor(field.name) do |value|
- value.present? ? { 'url' => value } : nil
+ FileField.new(value, base_url, self.updated_at)
end
end
@@ @@ -129,6 +129,19 @@ module Locomotive::Steam
end
end
+ # Represent a file
+ class FileField < Struct.new(:filename, :base, :updated_at)
+
+ def url
+ "#{base}/#{filename}"
+ end
+
+ def to_liquid
+ Locomotive::Steam::Liquid::Drops::UploadedFile.new(self)
+ end
+
+ end
+
end
end
locomotive/steam/liquid/drops/content_entry.rb b/lib/locomotive/steam/liquid/drops/content_entry.rb +6 -5
@@ @@ -26,7 +26,7 @@ module Locomotive
# {% endif %}
#
def next
- @next ||= repository.next(@_source).to_liquid
+ @next ||= repository(@_source).next(@_source).to_liquid
end
# Returns the previous content for the parent content type.
@@ @@ -39,7 +39,7 @@ module Locomotive
# {% endif %}
#
def previous
- @previous ||= repository.previous(@_source).to_liquid
+ @previous ||= repository(@_source).previous(@_source).to_liquid
end
def errors
@@ @@ -50,7 +50,7 @@ module Locomotive
return '' if @_source.nil?
if not @@forbidden_attributes.include?(meth.to_s)
- repository.with(@_source.content_type).value_for(@_source, meth, @context['with_scope'])
+ repository(@_source).value_for(@_source, meth, @context['with_scope'])
else
nil
end
@@ @@ -58,8 +58,9 @@ module Locomotive
protected
- def repository
- @context.registers[:services].repositories.content_entry
+ def repository(entry)
+ repository = @context.registers[:services].repositories.content_entry
+ repository.with(entry.content_type)
end
end
locomotive/steam/liquid/drops/upload_file.rb b/lib/locomotive/steam/liquid/drops/upload_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/tags/editable/file.rb b/lib/locomotive/steam/liquid/tags/editable/file.rb +9 -1
@@ @@ -17,7 +17,7 @@ module Locomotive
default_timestamp = context.registers[:page].updated_at.to_i
url, timestamp = (if element.source
- [element.source, default_timestamp]
+ [source_url(element), default_timestamp]
else
if element.default_source_url.present?
[element.default_source_url, default_timestamp]
@@ @@ -29,6 +29,14 @@ module Locomotive
context.registers[:services].asset_host.compute(url, timestamp)
end
+ def source_url(element)
+ if element.source =~ /^https?/
+ element.source
+ else
+ "#{element.base_url}/#{element.source}"
+ end
+ end
+
end
::Liquid::Template.register_tag('editable_file'.freeze, File)
locomotive/steam/models/entity.rb b/lib/locomotive/steam/models/entity.rb +1 -1
@@ @@ -5,7 +5,7 @@ module Locomotive::Steam
include Locomotive::Steam::Models::Concerns::Validation
- attr_accessor :attributes, :localized_attributes
+ attr_accessor :attributes, :localized_attributes, :base_url
def initialize(attributes)
@attributes = attributes.with_indifferent_access
locomotive/steam/models/mapper.rb b/lib/locomotive/steam/models/mapper.rb +10 -3
@@ @@ -24,6 +24,12 @@ module Locomotive::Steam
def localized_attributes(*args)
@localized_attributes += [*args]
+
+ @localized_attributes_hash = @localized_attributes.inject({}) do |hash, attribute|
+ hash[attribute.to_sym] = true; hash
+ end
+
+ @localized_attributes
end
def default_attribute(name, value)
@@ @@ -43,11 +49,12 @@ module Locomotive::Steam
def to_entity(attributes)
entity_klass.new(deserialize(attributes)).tap do |entity|
attach_entity_to_associations(entity)
+
set_default_attributes(entity)
- entity.localized_attributes = localized_attributes.inject({}) do |hash, attribute|
- hash[attribute.to_sym] = true; hash
- end
+ entity.localized_attributes = @localized_attributes_hash || {}
+
+ entity.base_url = @repository.base_url(entity)
end
end
locomotive/steam/models/repository.rb b/lib/locomotive/steam/models/repository.rb +4 -0
@@ @@ -61,6 +61,10 @@ module Locomotive::Steam
mapper.i18n_value_of(entity, name, locale)
end
+ def base_url(entity = nil)
+ adapter.base_url(mapper, scope, entity)
+ end
+
def prepare_conditions(*conditions)
first = { order_by: @local_conditions.delete(:order_by) }.delete_if { |_, v| v.blank? }
locomotive/steam/repositories/content_entry_repository.rb b/lib/locomotive/steam/repositories/content_entry_repository.rb +7 -2
@@ @@ -12,6 +12,7 @@ module Locomotive
@scope = Locomotive::Steam::Models::Scope.new(site, locale)
@content_type_repository = content_type_repository
@local_conditions = {}
+ @memoized_mappers = {}
end
# Entity mapping
@@ @@ -98,8 +99,12 @@ module Locomotive
private
- def mapper(memoized = false)
- super(memoized).tap do |mapper|
+ def mapper
+ key = self.content_type._id.to_s
+
+ return @memoized_mappers[key] if @memoized_mappers[key]
+
+ @memoized_mappers[key] = super(false).tap do |mapper|
add_localized_fields_to_mapper(mapper)
add_associations_to_mapper(mapper)
end
locomotive/steam/repositories/theme_asset_repository.rb b/lib/locomotive/steam/repositories/theme_asset_repository.rb +1 -1
@@ @@ -9,7 +9,7 @@ module Locomotive
mapping :theme_assets, entity: ThemeAsset
def url_for(path)
- [adapter.theme_assets_base_url(scope), path].join('/')
+ "#{base_url}/#{path}"
end
def checksums
locomotive/steam/services/editable_element_service.rb b/lib/locomotive/steam/services/editable_element_service.rb +3 -1
@@ @@ -7,7 +7,9 @@ module Locomotive
def find(page, block, slug)
decorate do
- repository.editable_element_for(page, block, slug)
+ repository.editable_element_for(page, block, slug).tap do |element|
+ element.base_url = repository.base_url(page) if element
+ end
end
end
spec/unit/decorators/i18n_decorator_spec.rb +0 -15
@@ @@ -64,19 +64,4 @@ describe Locomotive::Steam::Decorators::I18nDecorator do
Locomotive::Steam::Models::I18nField.new(name, translations)
end
- # describe 'with a model' do
-
- # let(:model) { Locomotive::Steam::Site.new(name: 'Acme') }
- # let(:decorated) { Locomotive::Steam::Decorators::I18nDecorator.new(model, nil, locale, default_locale) }
-
- # it 'runs some basic tests' do
- # pending
- # # expect(model.localized_attributes).to eq [:seo_title, :meta_description, :meta_keywords]
- # # expect(model.class.localized_attributes).to eq [:seo_title, :meta_description, :meta_keywords]
- # # expect(decorated.name).to eq 'Acme'
- # # expect(decorated.meta_description).to eq nil
- # end
-
- # end
-
end
spec/unit/entities/content_entry_spec.rb +3 -2
@@ @@ -134,10 +134,11 @@ describe Locomotive::Steam::ContentEntry do
context 'a file' do
let(:field_type) { :file }
let(:value) { 'foo.png' }
- it { is_expected.to eq({ 'url' => 'foo.png' }) }
+ it { expect(subject.url).to eq('/foo.png') }
context 'localized' do
let(:value) { build_i18n_field(en: 'foo-en.png', fr: 'foo-fr.png') }
- it { expect(subject.translations).to eq('en' => { 'url' => 'foo-en.png' }, 'fr' => { 'url' => 'foo-fr.png' }) }
+ it { expect(subject.translations[:en].url).to eq('/foo-en.png') }
+ it { expect(subject.translations[:fr].url).to eq('/foo-fr.png') }
end
end
spec/unit/liquid/tags/editable/file_spec.rb +2 -2
@@ @@ -70,7 +70,7 @@ describe Locomotive::Steam::Liquid::Tags::Editable::File do
let(:inline_editing) { false }
let(:page) { instance_double('Page', fullpath: 'hello-world', updated_at: DateTime.parse('2007-06-29 21:00:00')) }
- let(:element) { instance_double('EditableFile', id: 42, default_source_url: nil, source?: false, source: nil) }
+ let(:element) { instance_double('EditableFile', id: 42, default_source_url: nil, source?: false, source: nil, base_url: '') }
let(:services) { Locomotive::Steam::Services.build_instance(nil) }
let(:context) { ::Liquid::Context.new({}, {}, { page: page, services: services }) }
@@ @@ -97,7 +97,7 @@ describe Locomotive::Steam::Liquid::Tags::Editable::File do
context 'modified value' do
let(:file) { 'http://www.placehold.it/250x250' }
- let(:element) { instance_double('EditableFile', source: file, source?: true, default_source_url: false) }
+ let(:element) { instance_double('EditableFile', source: file, source?: true, default_source_url: false, base_url: '') }
it { is_expected.to eq 'http://www.placehold.it/250x250?1183150800' }
end
spec/unit/models/mapper_spec.rb +3 -3
@@ @@ -2,7 +2,7 @@ require 'spec_helper'
describe Locomotive::Steam::Models::Mapper do
- let(:repository) { instance_double('Repository') }
+ let(:repository) { instance_double('Repository', base_url: '') }
let(:name) { 'pages' }
let(:options) { { entity: MyPage } }
let(:block) { nil }
@@ @@ -24,7 +24,7 @@ describe Locomotive::Steam::Models::Mapper do
describe 'default attributes' do
let(:attributes) { { title: 'Hello world' } }
- let(:repository) { instance_double('Repository', my_site: 42) }
+ let(:repository) { instance_double('Repository', my_site: 42, base_url: '') }
let(:block) { ->(_) { default_attribute(:site, -> (repository) { repository.my_site }) } }
it { expect(subject.site).to eq 42 }
@@ @@ -33,7 +33,7 @@ describe Locomotive::Steam::Models::Mapper do
describe 'association' do
- let(:repository) { instance_double('Repository', scope: 42) }
+ let(:repository) { instance_double('Repository', scope: 42, base_url: '') }
let(:attributes) { { parents: [instance_double('Page', title: 'Hello world')] } }
let(:klass) { instance_double('RepositoryKlass')}
let(:block) { ->(_) { embedded_association(:parents, BlankRepository) } }