From c1b21fac8b38e59b29eea4d7d7f4420bd13e9b80 Mon Sep 17 00:00:00 2001 From: dinedine Date: Tue, 19 Oct 2010 12:20:09 +0200 Subject: [PATCH] use BSON::ObjectId to find elements (asset collection, content type) + make the import module work with S3 --- Gemfile | 4 +- Gemfile.lock | 34 +++++----- app/controllers/admin/imports_controller.rb | 29 ++++++--- app/models/asset_collection.rb | 8 ++- app/models/content_type.rb | 2 +- app/uploaders/theme_uploader.rb | 15 +++++ config/environments/production.rb | 2 + config/locales/default_en.yml | 1 + config/locales/default_fr.yml | 1 + config/mongoid.yml | 3 +- doc/TODO | 1 + lib/locomotive/import/job.rb | 69 ++++++++++++++++++--- lib/locomotive/liquid/tags/consume.rb | 2 +- 13 files changed, 127 insertions(+), 44 deletions(-) create mode 100644 app/uploaders/theme_uploader.rb diff --git a/Gemfile b/Gemfile index acf46466..36d0ef7d 100644 --- a/Gemfile +++ b/Gemfile @@ -17,9 +17,9 @@ gem 'formtastic', '>= 1.1.0' gem 'inherited_resources', '>= 1.1.2' gem 'rmagick', '= 2.12.2' -gem 'locomotive_carrierwave', :require => 'carrierwave' +gem 'locomotive_carrierwave', '0.5.0.1.beta2', :require => 'carrierwave' -gem 'custom_fields', '1.0.0.beta' +gem 'custom_fields', '1.0.0.beta2' gem 'fog', '0.3.7' gem 'mimetype-fu' gem 'actionmailer-with-request' diff --git a/Gemfile.lock b/Gemfile.lock index 304853dc..6b1e0fd8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -61,10 +61,8 @@ GEM rack (>= 1.0.0) rack-test (>= 0.5.4) selenium-webdriver (>= 0.0.3) - carrierwave (0.5.0) - activesupport (~> 3.0.0) cgi_multipart_eof_fix (2.5.0) - childprocess (0.0.9) + childprocess (0.1.3) ffi (~> 0.6.3) columnize (0.3.1) configuration (1.1.0) @@ -78,9 +76,9 @@ GEM cucumber-rails (0.3.2) cucumber (>= 0.8.0) culerity (0.2.12) - custom_fields (1.0.0.beta) + custom_fields (1.0.0.beta2) activesupport (>= 3.0.0) - carrierwave + locomotive_carrierwave mongoid (>= 2.0.0.beta.18) daemons (1.1.0) database_cleaner (0.5.2) @@ -124,7 +122,7 @@ GEM growl-glue (1.0.7) haml (3.0.18) has_scope (0.5.0) - heroku (1.10.14) + heroku (1.10.16) json_pure (>= 1.2.0, < 1.5.0) launchy (~> 0.3.2) rest-client (>= 1.4.0, < 1.7.0) @@ -140,7 +138,7 @@ GEM configuration (>= 0.0.5) rake (>= 0.8.1) linecache (0.43) - locomotive_carrierwave (0.5.0.1) + locomotive_carrierwave (0.5.0.1.beta2) activesupport (~> 3.0) locomotive_liquid (2.2.2) locomotive_mongoid_acts_as_tree (0.1.5.1) @@ -190,16 +188,16 @@ GEM rest-client (1.6.1) mime-types (>= 1.16) rmagick (2.12.2) - rspec (2.0.0) - rspec-core (= 2.0.0) - rspec-expectations (= 2.0.0) - rspec-mocks (= 2.0.0) - rspec-core (2.0.0) - rspec-expectations (2.0.0) + rspec (2.0.1) + rspec-core (~> 2.0.1) + rspec-expectations (~> 2.0.1) + rspec-mocks (~> 2.0.1) + rspec-core (2.0.1) + rspec-expectations (2.0.1) diff-lcs (>= 1.1.2) - rspec-mocks (2.0.0) - rspec-core (= 2.0.0) - rspec-expectations (= 2.0.0) + rspec-mocks (2.0.1) + rspec-core (~> 2.0.1) + rspec-expectations (~> 2.0.1) rspec-rails (2.0.1) rspec (~> 2.0.0) ruby-debug (0.10.3) @@ -238,7 +236,7 @@ DEPENDENCIES cgi_multipart_eof_fix cucumber (= 0.8.5) cucumber-rails - custom_fields (= 1.0.0.beta) + custom_fields (= 1.0.0.beta2) database_cleaner delayed_job (= 2.1.0.pre2) delayed_job_mongoid (= 1.0.0.rc) @@ -253,7 +251,7 @@ DEPENDENCIES httparty (>= 0.6.1) inherited_resources (>= 1.1.2) launchy - locomotive_carrierwave + locomotive_carrierwave (= 0.5.0.1.beta2) locomotive_liquid (= 2.2.2) locomotive_mongoid_acts_as_tree (= 0.1.5.1) mimetype-fu diff --git a/app/controllers/admin/imports_controller.rb b/app/controllers/admin/imports_controller.rb index f1fd15cc..a32bf495 100644 --- a/app/controllers/admin/imports_controller.rb +++ b/app/controllers/admin/imports_controller.rb @@ -23,28 +23,39 @@ module Admin def new; end def create - if params[:zipfile].blank? - @error = t('errors.messages.blank') - flash[:alert] = t('flash.admin.imports.create.alert') - render 'new' - else - path = self.store_zipfile! + identifier = store_zipfile! - job = Locomotive::Import::Job.new(path, current_site) + if identifier + job = Locomotive::Import::Job.new(identifier, current_site) Delayed::Job.enqueue job, { :site => current_site, :job_type => 'import' } flash[:notice] = t('flash.admin.imports.create.notice') redirect_to admin_import_url + else + @error = t('errors.messages.invalid_theme_file') + flash[:alert] = t('flash.admin.imports.create.alert') + + render 'new' end end protected def store_zipfile! + return nil if params[:zipfile].blank? + file = CarrierWave::SanitizedFile.new(params[:zipfile]) - new_file = file.copy_to(File.join(Rails.root, 'tmp', 'files', current_site.id.to_s, file.filename)) - new_file.path + + uploader = ThemeUploader.new(current_site) + + begin + uploader.store!(file) + rescue CarrierWave::IntegrityError + return nil + end + + uploader.identifier end end diff --git a/app/models/asset_collection.rb b/app/models/asset_collection.rb index 440fc667..c733f9eb 100644 --- a/app/models/asset_collection.rb +++ b/app/models/asset_collection.rb @@ -53,14 +53,16 @@ class AssetCollection end def store_asset_positions! - return if @assets_order.nil? + return if @assets_order.blank? - @assets_order.split(',').each_with_index do |asset_id, index| + ids = @assets_order.split(',').collect { |id| BSON::ObjectId(id) } + + ids.each_with_index do |asset_id, index| self.assets.find(asset_id).position = index end self.assets.clone.each do |asset| - if !@assets_order.split(',').include?(asset._id) + if !ids.include?(asset._id) self.assets.delete(asset) asset.send(:delete) end diff --git a/app/models/content_type.rb b/app/models/content_type.rb index d9821a72..f87adfa8 100644 --- a/app/models/content_type.rb +++ b/app/models/content_type.rb @@ -68,7 +68,7 @@ class ContentType def sort_contents!(order) order.split(',').each_with_index do |id, position| - self.contents.find(id)._position_in_list = position + self.contents.find(BSON::ObjectId(id))._position_in_list = position end self.save end diff --git a/app/uploaders/theme_uploader.rb b/app/uploaders/theme_uploader.rb new file mode 100644 index 00000000..56a453a8 --- /dev/null +++ b/app/uploaders/theme_uploader.rb @@ -0,0 +1,15 @@ +class ThemeUploader < ::CarrierWave::Uploader::Base + + def store_dir + "sites/#{model.id}/tmp/themes" + end + + def cache_dir + "#{Rails.root}/tmp/uploads" + end + + def extension_white_list + %w(zip) + end + +end \ No newline at end of file diff --git a/config/environments/production.rb b/config/environments/production.rb index b9d301b5..0b6c4f30 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -46,3 +46,5 @@ Locomotive::Application.configure do config.active_support.deprecation = :notify end + +# TODO: Put your carrierwave config down here \ No newline at end of file diff --git a/config/locales/default_en.yml b/config/locales/default_en.yml index 24b69123..4a346137 100644 --- a/config/locales/default_en.yml +++ b/config/locales/default_en.yml @@ -13,6 +13,7 @@ en: array_too_short: "is too small (minimum element number is %{count})" liquid_syntax: "Liquid Syntax error, please check the syntax" liquid_extend: "The page extends a template which does not exist" + invalid_theme_file: "can't be blank or isn't a zip file" attributes: defaults: diff --git a/config/locales/default_fr.yml b/config/locales/default_fr.yml index 6f0f2dc0..c94ed7bd 100644 --- a/config/locales/default_fr.yml +++ b/config/locales/default_fr.yml @@ -34,6 +34,7 @@ fr: array_too_short: "est trop petit (le nombre minimum d'éléments est %{count})" liquid_syntax: "Erreur de syntaxe dans les sections de page, veuillez vérifier la syntaxe" liquid_extend: "La page étend le contenu d'une page qui n'existe pas" + invalid_theme_file: "doit être rempli ou n'est pas un fichier zip" attributes: defaults: diff --git a/config/mongoid.yml b/config/mongoid.yml index c4c29b91..994750c5 100644 --- a/config/mongoid.yml +++ b/config/mongoid.yml @@ -8,7 +8,8 @@ defaults: &defaults development: <<: *defaults - database: locomotive_dev + # database: locomotive_dev + database: locomotive_hosting_production test: <<: *defaults diff --git a/doc/TODO b/doc/TODO index 5a999444..55594acf 100644 --- a/doc/TODO +++ b/doc/TODO @@ -13,6 +13,7 @@ BOARD: - write my first tutorial about locomotive - rewrite the unzip process (for the import) +- bug with asset collections (assets disappear if we save the collection ?!) - refactor slugify method (use parameterize + create a module) - [content types] the "display column" selector should not include file types diff --git a/lib/locomotive/import/job.rb b/lib/locomotive/import/job.rb index 87bafcb7..843dadcc 100644 --- a/lib/locomotive/import/job.rb +++ b/lib/locomotive/import/job.rb @@ -4,10 +4,10 @@ module Locomotive module Import class Job - def initialize(theme_file, site = nil, enabled = {}) - raise "Theme zipfile not found" unless File.exists?(theme_file) + def initialize(identifier, site = nil, enabled = {}) + raise "Theme identifier not found" if identifier.blank? - @theme_file = theme_file + @identifier = identifier @site = site @enabled = enabled end @@ -17,7 +17,7 @@ module Locomotive end def perform - puts "theme_file = #{@theme_file} / #{@site.present?} / #{@enabled.inspect}" + self.log "theme identifier #{@identifier} / enabled steps = #{@enabled.inspect}" self.unzip! @@ -33,21 +33,72 @@ module Locomotive %w(site content_types assets asset_collections snippets pages).each do |step| if @enabled[step] != false + self.log "performing '#{step}' step" "Locomotive::Import::#{step.camelize}".constantize.process(context) @worker.update_attributes :step => step if @worker else - puts "skipping #{step}" + self.log "skipping #{step}" end end end + def success(worker) + self.log 'deleting original zip file' + + uploader = ThemeUploader.new(@site) + + uploader.retrieve_from_store!(@identifier) + + uploader.remove! + + self.log 'deleting working folder' + + FileUtils.rm_rf(themes_folder) rescue nil + end + protected - def unzip! - Zip::ZipFile.open(@theme_file) do |zipfile| - destination_path = File.join(Rails.root, 'tmp', 'themes', @site.id.to_s) + def log(message) + puts "\t[import_theme] #{message}" + end - FileUtils.rm_r destination_path, :force => true + def themes_folder + File.join(Rails.root, 'tmp', 'themes', @site.id.to_s) + end + + def prepare_folder + FileUtils.rm_rf self.themes_folder if File.exists?(self.themes_folder) + + FileUtils.mkdir_p(self.themes_folder) + end + + def retrieve_zip_file + uploader = ThemeUploader.new(@site) + + uploader.retrieve_from_store!(@identifier) + + if uploader.file.respond_to?(:url) + self.log 'file from remote storage' + + @theme_file = File.join(self.themes_folder, @identifier) + + File.open(@theme_file, 'w') { |f| f.write(uploader.file.read) } + else # local filesystem + self.log 'file from local storage' + + @theme_file = uploader.path + end + end + + def unzip! + self.prepare_folder + + self.retrieve_zip_file + + self.log "unzip #{@theme_file}" + + Zip::ZipFile.open(@theme_file) do |zipfile| + destination_path = self.themes_folder zipfile.each do |entry| next if entry.name =~ /__MACOSX/ diff --git a/lib/locomotive/liquid/tags/consume.rb b/lib/locomotive/liquid/tags/consume.rb index dc02a79c..c8e62fa5 100644 --- a/lib/locomotive/liquid/tags/consume.rb +++ b/lib/locomotive/liquid/tags/consume.rb @@ -39,7 +39,7 @@ module Locomotive protected def render_all_and_cache_it(context) - Rails.cache.fetch(@cache_key, :expires_in => @expires_in) do + Rails.cache.fetch(@cache_key, :expires_in => @expires_in, :force => @expires_in == 0) do context.stack do context.scopes.last[@target.to_s] = Locomotive::Httparty::Webservice.consume(@url, @options.symbolize_keys)