Skip to content

Instantly share code, notes, and snippets.

@lackac
Created November 19, 2009 16:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lackac/238852 to your computer and use it in GitHub Desktop.
Save lackac/238852 to your computer and use it in GitHub Desktop.
Migrates a blog's contents from the Typo blog engine to Jekyll
# Author: Toby DiPasquale <toby@cbcg.net>
# Modified by: László Bácsi <lackac@lackac.hu>
require 'fileutils'
require 'rubygems'
require 'sequel'
require 'htmlentities'
begin
require 'ya2yaml'
$KCODE = 'u'
YAML_METHOD = :ya2yaml
rescue LoadError
YAML_METHOD = :to_yaml
end
class String
def decode_entities
coder = HTMLEntities.new
coder.decode(self)
end
end
module Jekyll
module Typo
# this SQL *should* work for both MySQL and PostgreSQL, but I haven't
# tested PostgreSQL yet (as of 2008-12-16)
SQL = <<-EOS
SELECT c.id id,
c.type type,
c.title title,
COALESCE(c.permalink, c.name) slug,
c.body body,
c.extended extended,
c.keywords tags,
c.published_at date,
c.state state,
COALESCE(tf.name, 'html') filter
FROM contents c
LEFT OUTER JOIN text_filters tf
ON c.text_filter_id = tf.id
EOS
def self.process dbname, user, pass, host='localhost'
FileUtils.mkdir_p '_posts'
db = Sequel.mysql dbname, :user => user, :password => pass, :host => host
db[SQL].each do |post|
puts "#{post[:type]}: #{post[:title]}"
name = post[:slug].strip.tr('/', '-')
if post[:type] == "Article"
name = "#{post[:date].strftime("%Y-%m-%d")}-#{name}"
dir = '_posts'
layout = 'post'
else
post[:filter] = "html"
dir = 'pages'
layout = 'default'
end
# Can have more than one text filter in this field, but we just want
# the first one for this
name += '.' + post[:filter].split(' ')[0]
File.open("#{dir}/#{name}", 'w') do |f|
f.puts({ 'layout' => layout,
'title' => post[:title].to_s,
'created_at' => post[:date],
'tags' => post[:tags],
'typo_id' => post[:id]
}.delete_if { |k, v| v.nil? || v == '' }.send(YAML_METHOD))
f.puts '---'
f.puts post[:body].delete("\r").decode_entities
if post[:extended]
f.puts post[:extended].delete("\r").decode_entities
end
end
end
end
end # module Typo
end # module Jekyll
if __FILE__ == $PROGRAM_NAME
unless ARGV.size < 3
Jekyll::Typo.process(*ARGV)
else
puts "Usage: #{__FILE__} typo_db db_user db_pass [db_host]"
exit 1
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment