#!/usr/bin/env ruby # TypePad converter for typo by Justin Johnson # # No need to make a backup of the original blog, since you'll just be # importing from the TypePad export. # # Even so, this script is still PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND. require File.dirname(__FILE__) + '/../../config/environment' require 'optparse' class TypePadMigrate attr_accessor :options def initialize self.options = {} self.parse_options self.convert_entries end def convert_entries entries = File.read(self.options[:file]).split('--------') puts "Converting #{entries.length} entries..." entries.each do |e| article_pattern1 = /AUTHOR:\s*([^\n]*)\n TITLE:\s*([^\n]*)\n STATUS:\s*([^\n]*)\n ALLOW\sCOMMENTS:\s*([^\n]*)\n CONVERT\sBREAKS:\s*([^\n]*)\n ALLOW\sPINGS:\s*([^\n]*)\n /mx article_cat_pattern = /CATEGORY:\s*([^\n]*)\n/mx article_pattern2 = /DATE:\s*([^\n]*)\n -----\n BODY:\s*(.*?)\n -----\n EXTENDED\sBODY:\s*(.*?)\n -----\n EXCERPT:\s*(.*?)\n -----\n KEYWORDS:\s*([^\n]*)\n ----- /mx comment_pattern = /COMMENT:\n AUTHOR:\s*([^\n]*)\n EMAIL:\s*([^\n]*)\n IP:\s*([^\n]*)\n URL:\s*([^\n]*)\n DATE:\s*([^\n]*)\n (.*?)\n ----- /mx comments = [] categories = [] article_attributes = {} if e =~ /#{article_pattern1}/ article_attributes[:author] = $1 article_attributes[:title] = $2 article_attributes[:published] = 1 article_attributes[:allow_comments] = $4 article_attributes[:allow_pings] = $6 e.sub!(/#{article_pattern1}/, '') end while e =~ /#{article_cat_pattern}/ categories << $1 e.sub!(/#{article_cat_pattern}/, '') end if e =~ /#{article_pattern2}/ article_attributes[:published_at] = $1 article_attributes[:created_at] = $1 article_attributes[:body] = $2 #article_attributes[:extended_html] = $3 article_attributes[:excerpt] = $4 article_attributes[:keywords] = $5 e.sub!(/#{article_pattern2}/, '') end while e =~ /#{comment_pattern}/ comments << {:author => $1, :email => $2, :ip => $3, :url => $4, :created_at => $5, :body => $6} e.sub!(/#{comment_pattern}/, '') end #article_attributes[:blog] = self.options[:blogname] if article_attributes.has_key?(:author) puts "Converting '#{article_attributes[:title]}'" a = Article.create(article_attributes) categories.each do |cat| Category.create(:name => cat) unless Category.find_by_name(cat) end categories.each do |c| a.categories.push_with_attributes(Category.find_by_name(c), :is_primary => 0) end comments.each do |c| puts "Adding comment by #{c[:author]}" a.comments << Comment.create(c) end end end end def parse_options OptionParser.new do |opt| opt.banner = 'Usage: typepad.rb [options]' opt.on('-f', '--file FILE', 'Path to TypePad export file.') do |f| self.options[:file] = f end opt.on('-b', '--blogname BLOGNAME', 'Name of blog defined in Typo.') do |b| self.options[:blogname] = b end opt.on_tail('-h', '--help', 'Show this message.') do puts opt exit end opt.parse!(ARGV) end unless self.options.include?(:file) and self.options.include?(:blogname) puts 'See typepad.rb --help for help.' exit end end end TypePadMigrate.new