2012-02-19 09:38:56 +00:00
#!/usr/bin/env ruby
begin
require 'bundler/setup'
rescue LoadError
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
end
2012-02-20 00:15:43 +00:00
# ================ GLOBAL VARIABLES ==============
2012-04-25 17:09:46 +00:00
$database_name = 'locomotive_engine_dev'
$database_host = 'localhost'
$database_port = '27017'
# $database_username = '<your username>'
# $database_password = '<your password>'
2012-02-20 00:15:43 +00:00
2012-04-25 17:09:46 +00:00
$default_locale = 'en'
$locale_exceptions = { }
2012-02-20 00:15:43 +00:00
# Example:
2012-04-18 12:35:06 +00:00
# $locale_exceptions = {
# '4c082a9393d4330812000002' => 'fr',
# '4c2330706f40d50ae2000005' => 'fr',
# '4dc07643d800a53aea00035a' => 'fr',
# '4eb6aca89a976a0001000ebb' => 'fr'
# }
2012-02-20 00:15:43 +00:00
2012-04-25 17:09:46 +00:00
# no amazon S3
$s3 = false
# amazon S3 settings
# $s3 = true
# $s3_bucket = '<BUCKET_NAME>'
# $fog_storage_settings = {
# :provider => 'AWS',
# :aws_secret_access_key => '<AWS_SECRET_KEY>',
# :aws_access_key_id => '<AWS_ACCESS_KEY>'
# }
2012-02-20 00:15:43 +00:00
# ================ MONGODB ==============
2012-02-19 09:38:56 +00:00
require 'mongoid'
Mongoid . configure do | config |
2012-04-25 17:09:46 +00:00
db = config . master = Mongo :: Connection . new ( $database_host , $database_port ) . db ( $database_name )
if $database_username && $database_password
db . authenticate ( $database_username , $database_password )
end
2012-02-19 09:38:56 +00:00
end
2012-02-20 00:15:43 +00:00
db = Mongoid . config . master
2012-04-25 17:09:46 +00:00
def get_locale ( site_id )
$locale_exceptions [ site_id . to_s ] || $default_locale
end
2012-02-20 00:15:43 +00:00
2012-02-19 09:38:56 +00:00
puts " *************************************** "
puts " [LocomotiveCMS] Upgrade from 1.0 to 2.0 "
puts " *************************************** \n \n "
# assets -> locomotive_content_assets
if collection = db . collections . detect { | c | c . name == 'assets' }
new_collection = db . collections . detect { | c | c . name == 'locomotive_content_assets' }
new_collection . drop if new_collection
collection . rename 'locomotive_content_assets'
end
# content_types -> locomotive_content_types
if collection = db . collections . detect { | c | c . name == 'content_types' }
new_collection = db . collections . detect { | c | c . name == 'locomotive_content_types' }
new_collection . drop if new_collection
collection . rename 'locomotive_content_types'
contents_collection = db . collections . detect { | c | c . name == 'locomotive_content_entries' }
contents_collection = db . create_collection ( 'locomotive_content_entries' ) if contents_collection . nil?
collection . update ( { } , {
'$rename' = > {
'api_enabled' = > 'public_submission_enabled' ,
'api_accounts' = > 'public_submission_accounts' ,
'content_custom_fields' = > 'entries_custom_fields' ,
'content_custom_fields_version' = > 'entries_custom_fields_version' ,
} ,
'$unset' = > {
'content_custom_fields_counter' = > '1'
}
} , :multi = > true )
collection . find . each do | content_type |
2012-02-20 00:15:43 +00:00
locale = get_locale ( content_type [ 'site_id' ] )
2012-02-19 09:38:56 +00:00
label_field_name = ''
2012-02-20 00:15:43 +00:00
recipe = { 'name' = > " Entry #{ content_type [ '_id' ] } " , 'version' = > content_type [ 'content_custom_fields_version' ] , 'rules' = > [ ] }
2012-02-19 09:38:56 +00:00
operations = { '$set' = > { } , '$unset' = > { } }
contents = content_type [ 'contents' ]
custom_fields = content_type [ 'entries_custom_fields' ]
# fields
custom_fields . each_with_index do | field , index |
2012-04-25 17:09:46 +00:00
name , type = field [ '_alias' ] , field [ 'kind' ] . downcase
rule_options = { }
class_name = " Locomotive::Entry #{ field [ 'target' ] [ - 24 , 24 ] } " if field [ 'target' ]
2012-02-19 09:38:56 +00:00
case field [ 'kind' ]
when 'category'
2012-02-20 00:15:43 +00:00
type = 'select'
2012-02-19 09:38:56 +00:00
operations [ '$set' ] . merge! ( " entries_custom_fields. #{ index } .type " = > 'select' )
when 'has_one'
2012-02-20 00:15:43 +00:00
type = 'belongs_to'
2012-02-19 09:38:56 +00:00
operations [ '$set' ] . merge! ( " entries_custom_fields. #{ index } .type " = > 'belongs_to' )
when 'has_many'
2012-04-25 17:09:46 +00:00
if ! field [ 'reverse_lookup' ] . blank?
2012-02-20 00:15:43 +00:00
type = 'has_many'
2012-02-19 09:38:56 +00:00
operations [ '$set' ] . merge! ( " entries_custom_fields. #{ index } .type " = > 'has_many' )
# reverse_lookup -> inverse_of => hmmmmmmm
2012-04-25 17:09:46 +00:00
if _content_type = collection . find ( '_id' = > BSON :: ObjectId ( field [ 'target' ] [ - 24 , 24 ] ) ) . first
2012-02-19 09:38:56 +00:00
if _field = _content_type [ 'entries_custom_fields' ] . detect { | f | f [ '_name' ] == field [ 'reverse_lookup' ] }
operations [ '$set' ] . merge! ( " entries_custom_fields. #{ index } .inverse_of " = > _field [ '_alias' ] )
2012-04-25 17:09:46 +00:00
rule_options [ 'inverse_of' ] = _field [ '_alias' ]
2012-02-19 09:38:56 +00:00
end
end
else
2012-02-20 00:15:43 +00:00
type = 'many_to_many'
2012-02-19 09:38:56 +00:00
operations [ '$set' ] . merge! ( " entries_custom_fields. #{ index } .type " = > 'many_to_many' )
end
end
if %w( has_one has_many ) . include? ( field [ 'kind' ] )
operations [ '$set' ] . merge! ( " entries_custom_fields. #{ index } .class_name " = > class_name )
operations [ '$unset' ] . merge! ( {
" entries_custom_fields. #{ index } .target " = > '1' ,
" entries_custom_fields. #{ index } .reverse_lookup " = > '1'
} )
2012-04-25 17:09:46 +00:00
rule_options [ 'class_name' ] = class_name
2012-02-19 09:38:56 +00:00
end
if content_type [ 'highlighted_field_name' ] == field [ '_name' ]
operations [ '$set' ] . merge! ( {
'label_field_id' = > field [ '_id' ] ,
'label_field_name' = > field [ '_alias' ]
} )
label_field_name = field [ '_alias' ]
end
if content_type [ 'group_by_field_name' ] == field [ '_name' ]
operations [ '$set' ] . merge! ( 'group_by_field_id' = > field [ '_id' ] )
end
operations [ '$set' ] . merge! ( {
2012-02-20 00:15:43 +00:00
" entries_custom_fields. #{ index } .name " = > field [ '_alias' ] ,
" entries_custom_fields. #{ index } .type " = > type ,
" entries_custom_fields. #{ index } ._type " = > 'Locomotive::ContentTypeEntryField' ,
" entries_custom_fields. #{ index } .localized " = > false
2012-02-19 09:38:56 +00:00
} )
2012-02-20 00:15:43 +00:00
if field [ 'kind' ] == 'category'
options = field [ 'category_items' ] . map do | attributes |
{
'_id' = > attributes [ '_id' ] ,
'name' = > { locale = > attributes [ 'name' ] } ,
'position' = > attributes [ 'position' ]
}
end
rule_options [ 'select_options' ] = options
operations [ '$set' ] . merge! ( " entries_custom_fields. #{ index } .select_options " = > options )
end
2012-02-19 09:38:56 +00:00
operations [ '$unset' ] . merge! ( {
" entries_custom_fields. #{ index } ._name " = > '1' ,
" entries_custom_fields. #{ index } ._alias " = > '1' ,
" entries_custom_fields. #{ index } .kind " = > '1' ,
2012-02-20 00:15:43 +00:00
" entries_custom_fields. #{ index } .category_items " = > '1' ,
" entries_custom_fields. #{ index } .format " = > '1'
2012-02-19 09:38:56 +00:00
} )
2012-02-20 00:15:43 +00:00
recipe [ 'rules' ] << {
'name' = > name ,
'type' = > type ,
'required' = > field [ 'required' ] || false ,
'localized' = > false
} . merge ( rule_options )
2012-02-19 09:38:56 +00:00
end
operations [ '$set' ] . merge! ( {
'order_by' = > '_position'
} ) if content_type [ 'order_by' ] == '_position_in_list'
operations [ '$unset' ] . merge! ( {
'highlighted_field_name' = > '1' ,
'group_by_field_name' = > '1'
} )
# contents
2012-02-20 00:15:43 +00:00
( contents || [ ] ) . each_with_index do | content |
2012-04-25 17:09:46 +00:00
attributes = content . clone . keep_if { | k , v | %w( _id _slug _visible created_at updated_at ) . include? ( k ) }
2012-02-19 09:38:56 +00:00
attributes . merge! ( {
2012-02-20 00:15:43 +00:00
'content_type_id' = > content_type [ '_id' ] ,
'site_id' = > content_type [ 'site_id' ] ,
'_position' = > content [ '_position_in_list' ] ,
'_type' = > " Locomotive::Entry #{ content_type [ '_id' ] } " ,
'_label_field_name' = > label_field_name ,
'custom_fields_recipe' = > recipe
2012-02-19 09:38:56 +00:00
} )
2012-04-25 17:09:46 +00:00
# localized attributes
%w( seo_title meta_description meta_keywords ) . each do | name |
attributes [ name ] = { locale = > content [ name ] }
end
2012-02-19 09:38:56 +00:00
custom_fields . each do | field |
name , _name = field [ '_alias' ] , field [ '_name' ]
case field [ 'kind' ] # string, text, boolean, date, file, category, has_many, has_one
2012-04-25 17:09:46 +00:00
when 'string' , 'text' , 'date'
2012-02-19 09:38:56 +00:00
attributes [ name ] = content [ _name ]
2012-04-25 17:09:46 +00:00
when 'boolean'
attributes [ name ] = content [ _name ] == '1'
2012-02-19 09:38:56 +00:00
when 'file'
2012-02-20 00:15:43 +00:00
attributes [ name ] = content [ " #{ _name } _filename " ]
2012-02-19 09:38:56 +00:00
when 'category' , 'has_one'
attributes [ " #{ name } _id " ] = content [ _name ]
when 'has_many'
2012-04-25 17:09:46 +00:00
if ! field [ 'reverse_lookup' ] . blank?
2012-02-19 09:38:56 +00:00
# nothing to do
else
2012-04-25 17:09:46 +00:00
attributes [ " #{ name . singularize } _ids " ] = ( content [ _name ] || [ ] ) . map { | _id | BSON :: ObjectId ( _id ) }
2012-02-19 09:38:56 +00:00
end
end
end
# insert document
contents_collection . insert attributes
end
# save content_type
collection . update ( { '_id' = > content_type [ '_id' ] } , operations )
2012-02-20 00:15:43 +00:00
end
collection . update ( { } , { '$unset' = > { 'contents' = > '1' } } , :multi = > true )
end
2012-02-19 09:38:56 +00:00
2012-02-20 00:15:43 +00:00
# sites -> locomotive_sites
if collection = db . collections . detect { | c | c . name == 'sites' }
new_collection = db . collections . detect { | c | c . name == 'locomotive_sites' }
new_collection . drop if new_collection
collection . rename 'locomotive_sites'
2012-02-19 09:38:56 +00:00
2012-02-20 00:15:43 +00:00
# localize attributes
collection . find . each do | site |
locale = get_locale ( site [ '_id' ] )
2012-02-19 09:38:56 +00:00
2012-02-20 00:15:43 +00:00
attributes = { 'locales' = > [ locale ] }
%w( seo_title meta_keywords meta_description ) . each do | attr |
attributes [ attr ] = { locale = > site [ attr ] }
end
collection . update ( { '_id' = > site [ '_id' ] } , { '$set' = > attributes } )
2012-02-19 09:38:56 +00:00
end
2012-02-20 00:15:43 +00:00
end
2012-02-19 09:38:56 +00:00
2012-02-20 00:15:43 +00:00
# snippets -> locomotive_snippets
if collection = db . collections . detect { | c | c . name == 'snippets' }
new_collection = db . collections . detect { | c | c . name == 'locomotive_snippets' }
new_collection . drop if new_collection
collection . rename 'locomotive_snippets'
# localize template
collection . find . each do | snippet |
locale = get_locale ( snippet [ 'site_id' ] )
collection . update ( { '_id' = > snippet [ '_id' ] } , { '$set' = > { 'template' = > { locale = > snippet [ 'template' ] } } } )
end
2012-02-19 09:38:56 +00:00
end
2012-02-20 00:15:43 +00:00
# theme_assets -> locomotive_theme_assets
if collection = db . collections . detect { | c | c . name == 'theme_assets' }
new_collection = db . collections . detect { | c | c . name == 'locomotive_theme_assets' }
new_collection . drop if new_collection
collection . rename 'locomotive_theme_assets'
end
# accounts -> locomotive_accounts
if collection = db . collections . detect { | c | c . name == 'accounts' }
new_collection = db . collections . detect { | c | c . name == 'locomotive_accounts' }
new_collection . drop if new_collection
collection . rename 'locomotive_accounts'
end
# pages -> locomotive_pages
if collection = db . collections . detect { | c | c . name == 'pages' }
new_collection = db . collections . detect { | c | c . name == 'locomotive_pages' }
new_collection . drop if new_collection
collection . rename 'locomotive_pages'
parents_table = { }
collection . find . each do | page |
parents_table [ page [ '_id' ] ] = page [ 'parent_id' ]
locale = get_locale ( page [ 'site_id' ] )
modifications , removals = { } , { }
2012-04-25 17:09:46 +00:00
modifications [ 'locales' ] = [ locale ]
modifications [ 'response_type' ] = 'text/html'
2012-05-26 12:35:04 +00:00
%w( title slug fullpath raw_template serialized_template template_dependencies snippet_dependencies seo_title meta_keywords meta_description redirect_url ) . each do | attr |
2012-02-20 00:15:43 +00:00
modifications [ attr ] = { locale = > page [ attr ] }
end
if page [ 'templatized' ]
modifications [ 'target_klass_name' ] = " Locomotive::Entry #{ page [ 'content_type_id' ] } "
removals [ 'content_type_id' ] = '1'
end
# editable elements
( page [ 'editable_elements' ] || [ ] ) . each_with_index do | editable_element , index |
modifications [ " editable_elements. #{ index } ._type " ] = " Locomotive:: #{ editable_element [ '_type' ] } "
modifications [ " editable_elements. #{ index } .content " ] = { locale = > editable_element [ 'content' ] }
2012-04-25 17:09:46 +00:00
modifications [ " editable_elements. #{ index } .locales " ] = [ locale ]
2012-02-20 00:15:43 +00:00
if editable_element [ '_type' ] == 'EditableFile'
modifications [ " editable_elements. #{ index } .source " ] = { locale = > editable_element [ 'source_filename' ] }
removals [ " editable_elements. #{ index } .source_filename " ] = '1'
end
2012-04-18 12:35:06 +00:00
# FIXME: do not remember why I needed to run this code.
# Locomotive::Page.each do |page|
# page.editable_elements.each_with_index do |el, index|
# next if el._type != 'Locomotive::EditableFile' || el.attributes['source'].is_a?(Hash)
#
# value = el.attributes['source']
#
# page.collection.update({ '_id' => page._id }, { '$set' => { "editable_elements.#{index}.source" => { 'en' => value } } })
# end
# end
2012-02-20 00:15:43 +00:00
end
if page [ 'depth' ] == 0 && page [ 'fullpath' ] == '404'
modifications [ 'position' ] = 1
end
collection . update ( { '_id' = > page [ '_id' ] } , { '$set' = > modifications , '$unset' = > removals } )
end
2012-02-19 09:38:56 +00:00
2012-02-20 00:15:43 +00:00
# set parent ids
collection . find . each do | page |
parent_ids , page_cursor = [ ] , page [ '_id' ]
while ! parents_table [ page_cursor ] . nil?
parent_ids << parents_table [ page_cursor ]
page_cursor = parents_table [ page_cursor ]
end
collection . update ( { '_id' = > page [ '_id' ] } , { '$set' = > { 'parent_ids' = > parent_ids . reverse } } )
end
collection . update ( { } , { '$unset' = > { 'parts' = > '1' , 'path' = > '1' , 'layout_id' = > '1' } } , { :multi = > true } )
end
2012-05-29 20:13:41 +00:00
# Update Norwegian locale from 'no' to 'nb'
2012-05-29 23:24:28 +00:00
if collection = db . collections . detect { | c | c . name == 'locomotive_accounts' }
collection . update ( { 'locale' = > 'no' } , { '$set' = > { 'locale' = > 'nb' } } , { :multi = > true } )
2012-05-29 20:34:38 +00:00
end
2012-05-29 20:13:41 +00:00
2012-02-20 00:15:43 +00:00
# some cleaning
%w( asset_collections liquid_templates delayed_backend_mongoid_jobs ) . each do | name |
db . drop_collection name
end
2012-04-25 17:09:46 +00:00
# content entry assets
#
# Example:
# old sites/4c34fc86cc85f01e47000005/contents/content_instance/4dc15162ceedba763500011a/files/didier_plate.png
# new sites/4c34fc86cc85f01e47000005/content_entry{content_type_id}/4dc15162ceedba763500011a/files/didier_plate.png
collection = db . collections . detect { | c | c . name == 'locomotive_content_entries' }
if $s3
# Amazon S3 (AWS)
require 'fog'
connection = Fog :: Storage . new ( $fog_storage_settings )
bucket = connection . directories . detect { | d | d . key == $s3_bucket }
bucket . files . each do | file |
if file . key =~ / ^sites \/ ([a-f0-9]+) \/ contents \/ content_instance \/ ([a-f0-9]+) \/ files /
content_type_id = collection . find ( '_id' = > BSON :: ObjectId ( $2 ) ) . first [ 'content_type_id' ] . to_s
new_key = file . key . gsub ( 'contents/content_instance' , " content_entry #{ content_type_id } " )
puts " new file #{ new_key } "
# rename file by copying the original file to its new folder
bucket . files . create (
:key = > new_key ,
:body = > file . body ,
:public = > true
)
file . destroy # delete the file forever
end
end
else
Dir [ File . join ( File . dirname ( __FILE__ ) , '..' , 'public' , 'sites' , '**/*' ) ] . each do | path |
next if File . directory? ( path )
if path =~ / public \/ sites \/ ([a-f0-9]+) \/ contents \/ content_instance \/ ([a-f0-9]+) \/ files /
content_type_id = collection . find ( '_id' = > BSON :: ObjectId ( $2 ) ) . first [ 'content_type_id' ] . to_s
new_path = path . gsub ( 'contents/content_instance' , " content_entry #{ content_type_id } " )
puts " new file #{ new_path } "
# create the target folder
FileUtils . mkdir_p ( File . dirname ( new_path ) )
FileUtils . mv ( path , new_path )
end
end
# do some cleaning
Dir [ File . join ( File . dirname ( __FILE__ ) , '..' , 'public' , 'sites' , '*' , 'contents' ) ] . each do | folder |
puts " remove folder #{ folder } "
FileUtils . rm_rf folder
end
end
2012-06-04 21:23:03 +00:00
puts " \n \n \033 [1mImportant: \033 [22m in order to avoid a bug with sessions after upgrading to the 2.0 version, you have to change your secret token key by updating your config/initializers/secret_token.rb file \n \n "