class JekyllImport::Importers::MT
Constants
- MORE_CONTENT_SEPARATOR
- STATUS_DRAFT
- STATUS_PUBLISHED
- SUPPORTED_ENGINES
Public Class Methods
Source
# File lib/jekyll-import/importers/mt.rb, line 196 def self.comment_content(comment, _options = default_options) comment[:comment_text] end
Source
# File lib/jekyll-import/importers/mt.rb, line 192 def self.comment_date(comment) comment[:comment_modified_on] || comment[:comment_created_on] end
Different versions of MT
used different column names
Source
# File lib/jekyll-import/importers/mt.rb, line 200 def self.comment_file_dir_and_base_name(posts_name_by_id, comment, _options = default_options) post_basename = posts_name_by_id[comment[:comment_entry_id]].sub(%r!\.\w+$!, "") comment_id = comment[:comment_id] [post_basename, "#{comment_id}.markdown"] end
Source
# File lib/jekyll-import/importers/mt.rb, line 175 def self.comment_metadata(comment, options = default_options) metadata = { "layout" => "comment", "comment_id" => comment[:comment_id], "post_id" => comment[:comment_entry_id], "author" => encode(comment[:comment_author], options), "email" => comment[:comment_email], "commenter_id" => comment[:comment_commenter_id], "date" => comment_date(comment).strftime("%Y-%m-%d %H:%M:%S %z"), "visible" => comment[:comment_visible] == 1, "ip" => comment[:comment_ip], "url" => comment[:comment_url], } metadata end
Extracts metadata for YAML front matter from comment
Source
# File lib/jekyll-import/importers/mt.rb, line 235 def self.database_from_opts(options) engine = options.fetch("engine", "mysql") dbname = options.fetch("dbname") sequel_engine = engine == "mysql" ? "mysql2" : engine case engine when "sqlite" Sequel.sqlite(dbname) when "mysql", "postgres" db_connect_opts = { :host => options.fetch("host", "127.0.0.1"), :user => options.fetch("user"), :password => options.fetch("password", ""), } db_connect_opts = options["port"] if options["port"] Sequel.public_send( sequel_engine, dbname, db_connect_opts ) else abort("Unsupported engine: '#{engine}'. Must be one of #{SUPPORTED_ENGINES.join(", ")}") end end
Source
# File lib/jekyll-import/importers/mt.rb, line 12 def self.default_options { "blog_id" => nil, "categories" => true, "dest_encoding" => "utf-8", "src_encoding" => "utf-8", "comments" => false, } end
Source
# File lib/jekyll-import/importers/mt.rb, line 207 def self.encode(str, options = default_options) if str.respond_to?(:encoding) str.encode(options["dest_encoding"], options["src_encoding"]) else str end end
Source
# File lib/jekyll-import/importers/mt.rb, line 154 def self.extra_entry_text_empty?(post) post[:entry_text_more].nil? || post[:entry_text_more].strip.empty? end
Extracts text body from post
Source
# File lib/jekyll-import/importers/mt.rb, line 158 def self.post_content(post, _options = default_options) if extra_entry_text_empty?(post) post[:entry_text] else post[:entry_text] + "\n\n#{MORE_CONTENT_SEPARATOR}\n\n" + post[:entry_text_more] end end
Source
# File lib/jekyll-import/importers/mt.rb, line 149 def self.post_date(post) post[:entry_authored_on] || post[:entry_created_on] end
Different versions of MT
used different column names
Source
# File lib/jekyll-import/importers/mt.rb, line 166 def self.post_file_name(post, _options = default_options) date = post_date(post) slug = post[:entry_basename] file_ext = suffix(post[:entry_convert_breaks]) "#{date.strftime("%Y-%m-%d")}-#{slug}.#{file_ext}" end
Source
# File lib/jekyll-import/importers/mt.rb, line 133 def self.post_metadata(post, options = default_options) metadata = { "layout" => "post", "title" => encode(post[:entry_title], options), "date" => post_date(post).strftime("%Y-%m-%d %H:%M:%S %z"), "excerpt" => encode(post[:entry_excerpt].to_s, options), "mt_id" => post[:entry_id], "blog_id" => post[:entry_blog_id], "post_id" => post[:entry_id], # for link with comments "basename" => post[:entry_basename], } metadata["published"] = false if post[:entry_status] != STATUS_PUBLISHED metadata end
Extracts metadata for YAML front matter from post
Source
# File lib/jekyll-import/importers/mt.rb, line 71 def self.process(options) options = default_options.merge(options) comments = options.fetch("comments") posts_name_by_id = {} if comments db = database_from_opts(options) post_categories = db[:mt_placement].join(:mt_category, :category_id => :placement_category_id) FileUtils.mkdir_p "_posts" posts = db[:mt_entry] posts = posts.filter(:entry_blog_id => options["blog_id"]) if options["blog_id"] posts.each do |post| categories = post_categories.filter( :placement_entry_id => post[:entry_id] ).map { |ea| encode(ea[:category_basename], options) } file_name = post_file_name(post, options) data = post_metadata(post, options) data["categories"] = categories if !categories.empty? && options["categories"] yaml_front_matter = data.delete_if { |_, v| v.nil? || v == "" }.to_yaml # save post path for comment processing posts_name_by_id[data["post_id"]] = file_name if comments content = post_content(post, options) File.open("_posts/#{file_name}", "w") do |f| f.puts yaml_front_matter f.puts "---" f.puts encode(content, options) end end # process comment output, if enabled if comments FileUtils.mkdir_p "_comments" comments = db[:mt_comment] comments.each do |comment| next unless posts_name_by_id.key?(comment[:comment_entry_id]) # if the entry exists dir_name, base_name = comment_file_dir_and_base_name(posts_name_by_id, comment, options) FileUtils.mkdir_p "_comments/#{dir_name}" data = comment_metadata(comment, options) content = comment_content(comment, options) yaml_front_matter = data.delete_if { |_, v| v.nil? || v == "" }.to_yaml File.open("_comments/#{dir_name}/#{base_name}", "w") do |f| f.puts yaml_front_matter f.puts "---" f.puts encode(content, options) end end end end
Main migrator function. Call this to perform the migration.
- dbname
-
The name of the database
- user
-
The database user name
- pass
-
The database user’s password
- host
-
The address of the MySQL database host. Default: ‘localhost’
- options
-
A hash of configuration options
Supported options are:
- blog_id
-
Specify a single MovableType blog to export by providing blog_id. Default: nil, importer will include posts for all blogs.
- categories
-
If true, save the post’s categories in its YAML front matter. Default: true
- src_encoding
-
Encoding of strings from the database. Default: UTF-8 If your output contains mangled characters, set src_encoding to something appropriate for your database charset.
- dest_encoding
-
Encoding of output strings. Default: UTF-8
- comments
-
If true, output comments in _comments directory, like the one mentioned at github.com/mpalmer/jekyll-static-comments/
Source
# File lib/jekyll-import/importers/mt.rb, line 22 def self.require_deps JekyllImport.require_with_fallback(%w( rubygems sequel sqlite3 mysql2 pg fileutils safe_yaml )) end
Source
# File lib/jekyll-import/importers/mt.rb, line 34 def self.specify_options(c) c.option "dbname", "--dbname DB", "Database name." c.option "user", "--user USER", "Database user name." c.option "engine", "--engine ENGINE", "Database engine ('mysql' or 'postgres'). (default: 'mysql')" c.option "password", "--password PW", "Database user's password. (default: '')" c.option "host", "--host HOST", "Database host name. (default: 'localhost')" c.option "port", "--port PORT", "Custom database port connect to. (default: null)" c.option "blog_id", "--blog_id ID", "Specify a single Movable Type blog ID to import. (default: null (all blogs))" c.option "categories", "--categories", "When true, save post's categories in its YAML front matter. (default: true)" c.option "src_encoding", "--src_encoding ENCODING", "Encoding of strings from database. (default: UTF-8)" c.option "dest_encoding", "--dest_encoding ENCODING", "Encoding of output strings. (default: UTF-8)" c.option "comments", "--comments", "When true, output comments in `_comments` directory. (default: false)" end
Source
# File lib/jekyll-import/importers/mt.rb, line 218 def self.suffix(entry_type) if entry_type.nil? || entry_type.include?("markdown") || entry_type.include?("__default__") # The markdown plugin I have saves this as # "markdown_with_smarty_pants", so I just look for "markdown". "markdown" elsif entry_type.include?("textile") # This is saved as "textile_2" on my installation of MT 5.1. "textile" elsif entry_type == "0" || entry_type.include?("richtext") # Richtext looks to me like it's saved as HTML, so I include it here. "html" else # Other values might need custom work. entry_type end end
Ideally, this script would determine the post format (markdown, html, etc) and create files with proper extensions. At this point it just assumes that markdown will be acceptable.