What did I do yesterday in the evening?
Well, I patched the [typosphere](http://www.typosphere.org) converter for movable type and migrated my blog :)
I just needed something to play with


#!/usr/bin/env ruby

  1. MovableType 3.x converter for typo by Patrick Lenz
    #
  2. MAKE BACKUPS OF EVERYTHING BEFORE RUNNING THIS SCRIPT!
  3. THIS SCRIPT IS PROVIDED "AS IS";, WITHOUT WARRANTY OF ANY KIND
    #
  4. Updated to work with current versions of ruby and MT by Marc Seeger
  5. I'm pretty much a ruby noob, but "it worked"; © :D

require File.dirname(FILE) + ‘/../../config/environment'
require ‘optparse'

class MTMigrate
attr_accessor :options

def initialize self.options = {} self.parse_options self.convert_categories self.convert_entries self.convert_prefs end def convert_categories mt_categories = ActiveRecord::Base.connection.select_all(%{ SELECT category_label AS name FROM `#{self.options[:mt_db]}`.mt_category WHERE category_blog_id = ‘#{self.options[:blog_id]}' }) puts "Converting #{mt_categories.size} categories.."; mt_categories.each do |cat| Category.create(cat) unless Category.find_by_name(cat[‘name']) end end def convert_entries default_filter = translate_filter ActiveRecord::Base.connection.select_all(%{ SELECT blog_convert_paras FROM `#{self.options[:mt_db]}`.mt_blog WHERE blog_id = ‘#{self.options[:blog_id]}' })0["blog_convert_paras";] mt_entries = ActiveRecord::Base.connection.select_all(%{ SELECT entry_id, entry_allow_comments AS allow_comments, entry_allow_pings AS allow_pings, entry_title AS title, entry_text AS body, entry_text_more AS extended, entry_excerpt AS excerpt, entry_convert_breaks AS convert_breaks, entry_keywords AS keywords, entry_authored_on AS created_at, entry_authored_on AS published_at, entry_modified_on AS updated_at, "published"; AS state, author_name AS author FROM `#{self.options[:mt_db]}`.mt_entry, `#{self.options[:mt_db]}`.mt_author WHERE entry_blog_id = ‘#{self.options[:blog_id]}' AND author_id = entry_author_id }) puts "Converting #{mt_entries.size} entries..";

current_entry = 1
mt_entries.each do |entry|

#### This is only some Information stuff
#### It basically lets you follow the process of converting the entries on the CLI
#### got the line refreshing code from http://snippets.dzone.com/posts/show/3760
# move cursor to beginning of line
cr = "\r";
# ANSI escape code to clear line from cursor to end of line
# "\e"; is an alternative to "\033";
# cf. http://en.wikipedia.org/wiki/ANSI_escape_code
clear = "\e[0K";
# reset lines
reset_line = cr + clear
print "#{reset_line} converting entry " + current_entry.to_s + "/#{mt_entries.size} ("; + entry[‘title'] + ")";
$stdout.flush
current_entry = current_entry + 1
#### This is only some Information stuff
a = Article.new
a.attributes = entry.reject { |k,v| k = /entry_id|convert_breaks/ }

if entry["convert_breaks";] == "default"; a.text_filter = default_filter else a.text_filter = translate_filter entry["convert_breaks";] end a.save
  1. Fetch category assignments
    ActiveRecord::Base.connection.select_all(%{
    SELECT category_label, placement_is_primary
    FROM `#{self.options[:mt_db]}`.mt_category, `#{self.options[:mt_db]}`.mt_entry, `#{self.options[:mt_db]}`.mt_placement
    WHERE entry_id = #{entry[‘entry_id']}
    AND category_id = placement_category_id
    AND entry_id = placement_entry_id
    }).each do |c|
  2. a.categories.push_with_attributes(Category.find_by_name(c[‘category_label']), :is_primary => c[‘placement_is_primary'])
    a.categorizations.create(:category => Category.find_by_name(c[‘category_label']), :is_primary => c[‘placement_is_primary'])
    end
  1. Fetch comments
    ActiveRecord::Base.connection.select_all(%{
    SELECT
    comment_author AS author,
    comment_email AS email,
    comment_url AS url,
    comment_text AS body,
    comment_created_on AS created_at,
    comment_modified_on AS updated_at
    FROM `#{self.options[:mt_db]}`.mt_comment
    WHERE comment_entry_id = #{entry[‘entry_id']}
    }).each do |c|
    a.comments.create©
    end
  1. Fetch trackbacks
    ActiveRecord::Base.connection.select_all(%{
    SELECT
    tbping_title AS title,
    tbping_excerpt AS excerpt,
    tbping_source_url AS url,
    tbping_ip AS ip,
    tbping_blog_name AS blog_name,
    tbping_created_on AS created_at,
    tbping_modified_on AS updated_at
    FROM `#{self.options[:mt_db]}`.mt_tbping, `#{self.options[:mt_db]}`.mt_trackback
    WHERE tbping_tb_id = trackback_id
    AND trackback_entry_id = #{entry[‘entry_id']}
    }).each do |tb|
    a.trackbacks.create(tb)
    end
    end
    end
def convert_prefs puts "\nConverting prefs"; ActiveRecord::Base.connection.select_one(%{ SELECT blog_name, blog_allow_comments_default AS default_allow_comments, blog_allow_pings_default AS default_allow_pings FROM `#{self.options[:mt_db]}`.mt_blog WHERE blog_id = ‘#{self.options[:blog_id]}' }).each do |pref_name, pref_value| begin Setting.find_by_name(pref_name).update_attribute("value";, pref_value) rescue Setting.create({'name' => pref_name, ‘value' => pref_value}) end end end def parse_options OptionParser.new do |opt| opt.banner = "Usage: mt3.rb [options]"; opt.on(‘—blog-id BLOGID', Integer, ‘Blog ID to import from.') { |i| self.options[:blog_id] = i } opt.on(‘—db DBNAME', String, ‘Movable Type database name.') { |d| self.options[:mt_db] = d } opt.on_tail(‘-h', ‘—help', ‘Show this message.') do puts opt exit end opt.parse!(ARGV) end unless self.options.include?(:blog_id) and self.options.include?(:mt_db) puts "See mt3.rb —help for help."; exit end end def translate_filter(input) return case input when /textile/: ‘textile' when /markdown/ : ‘markdown' else nil end end

end

MTMigrate.new

Comments