fix some bugs + refactor look and feel of the import screens (wip)

This commit is contained in:
did 2011-12-08 07:47:17 -08:00
parent b60b1378f8
commit a25009824c
24 changed files with 201 additions and 122 deletions

View File

@ -46,7 +46,7 @@ gem 'rubyzip'
gem 'actionmailer-with-request', '~> 0.3.0', :require => 'actionmailer_with_request' gem 'actionmailer-with-request', '~> 0.3.0', :require => 'actionmailer_with_request'
gem 'httparty', '~> 0.8.1' gem 'httparty', '~> 0.8.1'
gem 'delayed_job', '~> 3.0.0.pre4' gem 'delayed_job', '~> 3.0.0.pre4'
gem 'delayed_job_mongoid', '~> 1.0.6' gem 'delayed_job_mongoid', '~> 1.0.7'
gem 'SystemTimer', :platforms => :ruby_18 gem 'SystemTimer', :platforms => :ruby_18
# The rest of the dependencies are for use when in the locomotive dev environment # The rest of the dependencies are for use when in the locomotive dev environment

View File

@ -16,14 +16,6 @@ GIT
carrierwave-mongoid (~> 0.1.3) carrierwave-mongoid (~> 0.1.3)
mongoid (~> 2.3.3) mongoid (~> 2.3.3)
GIT
remote: git://github.com/nragaz/uploadify-rails.git
revision: 18353ceb8a8ed1b9839cc642d5806bcffb62eb15
specs:
uploadify-rails (1.0.1)
railties (~> 3.0)
thor (~> 0.14)
GIT GIT
remote: git://github.com/plataformatec/devise.git remote: git://github.com/plataformatec/devise.git
revision: ede004169c6af7416f8c4e3fc29a653bee133f60 revision: ede004169c6af7416f8c4e3fc29a653bee133f60
@ -133,8 +125,8 @@ GEM
delayed_job (3.0.0.pre4) delayed_job (3.0.0.pre4)
activesupport (~> 3.0) activesupport (~> 3.0)
daemons (= 1.0.10) daemons (= 1.0.10)
delayed_job_mongoid (1.0.6) delayed_job_mongoid (1.0.7)
delayed_job (= 3.0.0.pre4) delayed_job (~> 3.0.0.pre)
mongoid (>= 2.0) mongoid (>= 2.0)
diff-lcs (1.1.3) diff-lcs (1.1.3)
dragonfly (0.9.8) dragonfly (0.9.8)
@ -325,7 +317,7 @@ DEPENDENCIES
custom_fields! custom_fields!
database_cleaner database_cleaner
delayed_job (~> 3.0.0.pre4) delayed_job (~> 3.0.0.pre4)
delayed_job_mongoid (~> 1.0.6) delayed_job_mongoid (~> 1.0.7)
devise! devise!
dragonfly (~> 0.9.8) dragonfly (~> 0.9.8)
factory_girl_rails (~> 1.1) factory_girl_rails (~> 1.1)
@ -360,5 +352,4 @@ DEPENDENCIES
tinymce-rails tinymce-rails
uglifier (~> 1.0.4) uglifier (~> 1.0.4)
unicorn unicorn
uploadify-rails!
xpath (~> 0.1.4) xpath (~> 0.1.4)

View File

@ -10,7 +10,6 @@
//= require underscore //= require underscore
//= require handlebars //= require handlebars
//= require backbone //= require backbone
//= require uploadify
//= require codemirror //= require codemirror
//= require tinymce-jquery //= require tinymce-jquery
//= require codemirror/overlay //= require codemirror/overlay

View File

@ -0,0 +1,13 @@
Locomotive.Views.Import ||= {}
class Locomotive.Views.Import.NewView extends Backbone.View
el: '#content'
render: ->
super()
@enable_checkboxes()
enable_checkboxes: ->
@$('.formtastic input[type=checkbox]').checkToggle()

View File

@ -8,40 +8,18 @@ module Locomotive
before_filter :authorize_import before_filter :authorize_import
def show def show
@job = Delayed::Job.where({ :job_type => 'import', :site_id => current_site.id }).last @import = Locomotive::Import::Model.current(current_site)
respond_with @import
respond_to do |format|
format.html do
redirect_to new_import_url if @job.nil?
end
format.json { render :json => {
:step => @job.nil? ? 'done' : @job.step,
:failed => @job && @job.last_error.present?
} }
end
end end
def new def new
@import = Locomotive::Import::Model.new
respond_with @import
end end
def create def create
begin @import = Locomotive::Import::Model.create(params[:import].merge(:site => current_site))
Locomotive::Import::Job.run!(params[:zipfile], current_site, { respond_with @import, :location => Locomotive.config.delayed_job ? import_url : new_import_url
:samples => Boolean.set(params[:samples]),
:reset => Boolean.set(params[:reset])
})
flash[:notice] = t("fash.locomotive.import.create.#{Locomotive.config.delayed_job ? 'notice' : 'done'}")
redirect_to Locomotive.config.delayed_job ? import_url : new_import_url
rescue Exception => e
logger.error "[Locomotive import] #{e.message} / #{e.backtrace}"
@error = e.message
flash[:alert] = t('fash.locomotive.import.create.alert')
render 'new'
end
end end
protected protected
@ -52,3 +30,36 @@ module Locomotive
end end
end end
# begin
# Locomotive::Import::Job.run!(params[:zipfile], current_site, {
# :samples => Boolean.set(params[:samples]),
# :reset => Boolean.set(params[:reset])
# })
#
# flash[:notice] = t("fash.locomotive.import.create.#{Locomotive.config.delayed_job ? 'notice' : 'done'}")
#
# redirect_to Locomotive.config.delayed_job ? import_url : new_import_url
# rescue Exception => e
# logger.error "[Locomotive import] #{e.message} / #{e.backtrace}"
#
# @error = e.message
# flash[:alert] = t('fash.locomotive.import.create.alert')
#
# render 'new'
# end
# def show
# @job = Delayed::Job.where({ :job_type => 'import', :site_id => current_site.id }).last
#
# respond_to do |format|
# format.html do
# redirect_to new_import_url if @job.nil?
# end
# format.json { render :json => {
# :step => @job.nil? ? 'done' : @job.step,
# :failed => @job && @job.last_error.present?
# } }
# end
# end

View File

@ -84,8 +84,12 @@ module Locomotive
Locomotive::Liquid::Drops::Page.new(self) Locomotive::Liquid::Drops::Page.new(self)
end end
def to_presenter
Locomotive::PagePresenter.new(self)
end
def as_json(options = {}) def as_json(options = {})
Locomotive::PagePresenter.new(self).as_json self.to_presenter.as_json
end end
protected protected

View File

@ -26,8 +26,12 @@ module Locomotive
## methods ## ## methods ##
def to_presenter
Locomotive::SnippetPresenter.new(self)
end
def as_json(options = {}) def as_json(options = {})
Locomotive::SnippetPresenter.new(self).as_json self.to_presenter.as_json
end end
protected protected

View File

@ -30,9 +30,10 @@ class Locomotive::BasePresenter
%w(id created_at updated_at) %w(id created_at updated_at)
end end
def as_json def as_json(methods = nil)
methods ||= self.included_methods
{}.tap do |hash| {}.tap do |hash|
self.included_methods.map(&:to_sym).each do |meth| methods.map(&:to_sym).each do |meth|
hash[meth] = self.send(meth) rescue nil hash[meth] = self.send(meth) rescue nil
end end
end end

View File

@ -3,6 +3,10 @@ module Locomotive
delegate :title, :slug, :fullpath, :raw_template, :published, :template_changed, :cache_strategy, :to => :source delegate :title, :slug, :fullpath, :raw_template, :published, :template_changed, :cache_strategy, :to => :source
def escaped_raw_template
h(self.source.raw_template)
end
def editable_elements def editable_elements
self.source.enabled_editable_elements.collect(&:as_json) self.source.enabled_editable_elements.collect(&:as_json)
end end
@ -11,5 +15,10 @@ module Locomotive
super + %w(title slug fullpath raw_template published published cache_strategy template_changed editable_elements) super + %w(title slug fullpath raw_template published published cache_strategy template_changed editable_elements)
end end
def as_json_for_html_view
methods = included_methods.clone - %w(raw_template)
self.as_json(methods)
end
end end
end end

View File

@ -11,5 +11,10 @@ module Locomotive
super + %w(name slug template updated_at) super + %w(name slug template updated_at)
end end
def as_json_for_html_view
methods = included_methods.clone - %w(template)
self.as_json(methods)
end
end end
end end

View File

@ -18,7 +18,7 @@ module Locomotive
end end
def self.build(site, path) def self.build(site, path)
asset = ThemeAsset.new(:site => site, :folder => File.dirname(path)) asset = site.theme_assets.build(:folder => File.dirname(path))
uploader = ThemeAssetUploader.new(asset) uploader = ThemeAssetUploader.new(asset)
uploader.retrieve_from_store!(File.basename(path)) uploader.retrieve_from_store!(File.basename(path))
uploader uploader

View File

@ -5,29 +5,11 @@
%p!= t('.help') %p!= t('.help')
= form_tag import_url, :multipart => true, :class => 'formtastic import' do = semantic_form_for @import, :as => 'import', :url => import_url, :html => { :multipart => true } do |f|
%fieldset.inputs = f.inputs :name => :upload do
%legend = f.input :source, :as => 'file'
%span= t('formtastic.titles.upload') = f.input :samples, :as => :'Locomotive::Toggle'
%ol = f.input :reset, :as => :'Locomotive::Toggle'
%li{ :class => "file #{'error' if @error} required" }
= label_tag 'zipfile', t('formtastic.labels.import.new.source')
= file_field_tag 'zipfile'
- if @error
.inline-errors
%p= @error
%p.inline-hints= t('formtastic.hints.import.source')
%li.input.toggle = render 'locomotive/shared/form_actions', :back_url => edit_current_site_url, :button_label => :create
= label_tag 'samples', t('formtastic.labels.import.new.samples')
= check_box_tag 'samples'
%p.inline-hints= t('formtastic.hints.import.samples')
%li.input.toggle
= label_tag 'reset', t('formtastic.labels.import.new.reset')
= check_box_tag 'reset'
%p.inline-hints= t('formtastic.hints.import.reset')
= render 'locomotive/shared/form_actions', :button_label => :send

View File

@ -6,7 +6,7 @@
- if @page.persisted? - if @page.persisted?
- content_for :backbone_view_data do - content_for :backbone_view_data do
:plain :plain
{ page: #{@page.to_json} } { page: #{@page.to_presenter.as_json_for_html_view.to_json} }
- if can?(:manage, @page) - if can?(:manage, @page)

View File

@ -3,7 +3,7 @@
- content_for :backbone_view_data do - content_for :backbone_view_data do
:plain :plain
{ snippet: #{@snippet.persisted? ? @snippet.to_json : 'null'} } { snippet: #{@snippet.persisted? ? @snippet.to_presenter.as_json_for_html_view.to_json : 'null'} }
= f.inputs :name => :information do = f.inputs :name => :information do
= f.input :name, :wrapper_html => { :class => 'highlighted' } = f.input :name, :wrapper_html => { :class => 'highlighted' }

View File

@ -30,7 +30,8 @@ x edit my site
x delete in ajax x delete in ajax
x upload many files at once x upload many files at once
- import/export - import/export
- QU - export
- replace DJ by QU
- site picker - site picker
- content types - content types
- change in main menu - change in main menu

View File

@ -40,7 +40,8 @@ module Delayed
class Job class Job
field :job_type field :job_type
field :step field :step
referenced_in :site field :site_id, :type => BSON::ObjectId
# referenced_in :site
end end
end end
end end

View File

@ -27,9 +27,5 @@ module Locomotive
ActionController::Base.wrap_parameters :format => [:json] ActionController::Base.wrap_parameters :format => [:json]
end end
rake_tasks do
load "railties/tasks.rake"
end
end end
end end

View File

@ -1,5 +1,6 @@
require 'locomotive/import/logger' require 'locomotive/import/logger'
require 'locomotive/import/base' require 'locomotive/import/base'
require 'locomotive/import/model'
require 'locomotive/import/job' require 'locomotive/import/job'
require 'locomotive/import/site' require 'locomotive/import/site'
require 'locomotive/import/assets' require 'locomotive/import/assets'

View File

@ -5,7 +5,7 @@ module Locomotive
def process def process
self.add_theme_assets self.add_theme_assets
self.add_other_assets self.add_content_assets
end end
protected protected
@ -33,16 +33,16 @@ module Locomotive
end end
end end
def add_other_assets def add_content_assets
Dir[File.join(theme_path, 'public', 'samples', '*')].each do |asset_path| Dir[File.join(theme_path, 'public', 'samples', '*')].each do |asset_path|
next if File.directory?(asset_path) next if File.directory?(asset_path)
self.log "other asset = #{asset_path}" self.log "other asset = #{asset_path}"
asset = site.assets.where(:source_filename => File.basename(asset_path)).first asset = site.content_assets.where(:source_filename => File.basename(asset_path)).first
asset ||= self.site.assets.build asset ||= self.site.content_assets.build
asset.attributes = { :source => File.open(asset_path) } asset.attributes = { :source => File.open(asset_path) }

View File

@ -7,7 +7,7 @@ module Locomotive
include Logger include Logger
def initialize(zipfile, site, options = {}) def initialize(zipfile, site, options = {})
@site = site @site_id = site._id.to_s
@options = { @options = {
:reset => false, :reset => false,
:samples => false, :samples => false,
@ -18,15 +18,20 @@ module Locomotive
raise "Theme identifier not found" if @identifier.blank? raise "Theme identifier not found" if @identifier.blank?
@uploader = nil # fix issue with Ruby 1.9.2 and serialization # empty instance variables before serialization (issue with ruby 1.9.2)
@uploader = @site = nil
end end
def before(worker) def before(worker)
@worker = worker @worker = worker
end end
def site
@site ||= Locomotive::Site.find(@site_id)
end
def perform def perform
self.log "theme identifier #{@identifier}" self.log "theme identifier #{@identifier} / site_id #{@site_id}"
self.unzip! self.unzip!
@ -34,7 +39,7 @@ module Locomotive
context = { context = {
:database => @database, :database => @database,
:site => @site, :site => self.site,
:theme_path => @theme_path, :theme_path => @theme_path,
:error => nil, :error => nil,
:worker => @worker :worker => @worker
@ -42,20 +47,22 @@ module Locomotive
self.reset! if @options[:reset] self.reset! if @options[:reset]
%w(site content_types content_assets snippets pages).each do |step| # %w(site content_types content_assets snippets pages).each do |step|
%w(site assets snippets pages).each do |step|
if @options[:enabled][step] != false if @options[:enabled][step] != false
"Locomotive::Import::#{step.camelize}".constantize.process(context, @options) "Locomotive::Import::#{step.camelize}".constantize.process(context, @options)
@worker.update_attributes :step => step if @worker @worker.update_attributes :step => step if @worker
else else
self.log "skipping #{step}" self.log "skipping #{step}"
end end
sleep 10 # FIXME DEBUG PURPOSE
end end
end end
def success(worker) def success(worker)
self.log 'deleting original zip file' self.log 'deleting original zip file'
uploader = self.get_uploader(@site) uploader = self.get_uploader(self.site)
uploader.retrieve_from_store!(@identifier) uploader.retrieve_from_store!(@identifier)
@ -70,8 +77,7 @@ module Locomotive
job = self.new(zipfile, site, options) job = self.new(zipfile, site, options)
if Locomotive.config.delayed_job if Locomotive.config.delayed_job
puts "delayed::JOB !" Delayed::Job.enqueue job, { :site_id => site._id, :job_type => 'import' }
Delayed::Job.enqueue job, { :site => site, :job_type => 'import' }
else else
job.perform job.perform
end end
@ -80,7 +86,7 @@ module Locomotive
protected protected
def themes_folder def themes_folder
File.join(Rails.root, 'tmp', 'themes', @site.id.to_s) File.join(Rails.root, 'tmp', 'themes', self.site._id.to_s)
end end
def prepare_folder def prepare_folder
@ -92,7 +98,7 @@ module Locomotive
def store_zipfile(zipfile) def store_zipfile(zipfile)
return nil if zipfile.blank? return nil if zipfile.blank?
uploader = self.get_uploader(@site) uploader = self.get_uploader(self.site)
begin begin
if zipfile.is_a?(String) && zipfile =~ /^https?:\/\// if zipfile.is_a?(String) && zipfile =~ /^https?:\/\//
@ -109,7 +115,7 @@ module Locomotive
end end
def retrieve_zipfile def retrieve_zipfile
uploader = self.get_uploader(@site) uploader = self.get_uploader(self.site)
uploader.retrieve_from_store!(@identifier) uploader.retrieve_from_store!(@identifier)
@ -161,10 +167,10 @@ module Locomotive
end end
def reset! def reset!
@site.pages.destroy_all self.site.pages.destroy_all
@site.content_assets.destroy_all self.site.content_assets.destroy_all
@site.theme_assets.destroy_all self.site.theme_assets.destroy_all
@site.content_types.destroy_all self.site.content_types.destroy_all
end end
def get_uploader(site) def get_uploader(site)

View File

@ -0,0 +1,70 @@
module Locomotive
module Import
class Model
include Logger
include ActiveModel::Validations
## fields ##
attr_accessor :site, :source, :reset, :samples, :enabled
## validation ##
validates :site, :source, :presence => true
def initialize(attributes = {})
attributes = HashWithIndifferentAccess.new(attributes)
self.site = attributes[:site]
self.source = attributes[:source]
self.reset = attributes[:reset] || false
self.samples = attributes[:samples] || false
self.enabled = attributes[:enabled] || {}
end
def reset=(value)
@reset = Boolean.set(value)
end
def samples=(value)
@samples = Boolean.set(value)
end
## methods ##
def to_job
new Job()
end
def to_key
['import']
end
## class methods ##
def self.create(attributes = {})
puts attributes.inspect
new(attributes).tap do |job|
if job.valid?
begin
self.launch!(job)
rescue Exception => e
job.log "#{e.message}\n#{e.backtrace}"
job.errors.add(:source, e.message)
end
end
end
end
def self.launch!(job)
Locomotive::Import::Job.run! job.source, job.site, {
:reset => job.reset,
:enabled => job.enabled
}
end
def self.name
'Import'
end
end
end
end

View File

@ -64,12 +64,13 @@ module Locomotive
attributes[:position] = attributes[:position].to_i attributes[:position] = attributes[:position].to_i
# templatized ? # templatized ?
if content_type_slug = attributes.delete(:content_type) # TODO: DEBUG PURPOSE
attributes.merge!({ # if content_type_slug = attributes.delete(:content_type)
:templatized => true, # attributes.merge!({
:content_type => site.content_types.where(:slug => content_type_slug).first # :templatized => true,
}) # :content_type => site.content_types.where(:slug => content_type_slug).first
end # })
# end
# redirection page ? # redirection page ?
attributes[:redirect] = true if attributes[:redirect_url].present? attributes[:redirect] = true if attributes[:redirect_url].present?
@ -153,7 +154,7 @@ module Locomotive
template.gsub!(/\/samples\/(.*\.[a-zA-Z0-9]{3})/) do |match| template.gsub!(/\/samples\/(.*\.[a-zA-Z0-9]{3})/) do |match|
name = File.basename($1) name = File.basename($1)
if asset = site.assets.where(:source_filename => name).first if asset = site.content_assets.where(:source_filename => name).first
asset.source.url asset.source.url
else else
match match

View File

@ -1,16 +0,0 @@
# Re-definitions are appended to existing tasks
# Embed tasks from Delayed_job
namespace :jobs do
desc "Clear the delayed_job queue."
task :clear => :environment do
Delayed::Job.delete_all
end
desc "Start a delayed_job worker."
task :work => :environment do
puts "Delayed::Job.new = #{Delayed::Job.new.inspect}"
::Delayed::Worker.new(:min_priority => ENV['MIN_PRIORITY'], :max_priority => ENV['MAX_PRIORITY']).start
end
end

View File

@ -42,7 +42,7 @@ Locomotive.configure do |config|
# If you do not mind about importing theme without DelayedJob, disable it. # If you do not mind about importing theme without DelayedJob, disable it.
# #
# Warning: this option is not used if you deploy on bushi.do and we set automatically the value to true. # Warning: this option is not used if you deploy on bushi.do and we set automatically the value to true.
config.delayed_job = false config.delayed_job = true # false
# configure how many items we display in sub menu in the "Contents" section. # configure how many items we display in sub menu in the "Contents" section.
# config.lastest_items_nb = 5 # config.lastest_items_nb = 5