module JekyllImport::Importers::DrupalCommon::ClassMethods

This module provides a base for the Drupal importers (at least for 6 and 7; since 8 will be a different beast). Version-specific importers will need to implement the missing methods from the Importer class.

The general idea is that this importer reads a MySQL database via Sequel and creates a post file for each node it finds in the Drupal database.

Constants

DEFAULTS

Public Instance Methods

process(options) click to toggle source
# File lib/jekyll-import/importers/drupal_common.rb, line 49
        def process(options)
          dbname = options.fetch("dbname")
          user   = options.fetch("user")
          engine = options.fetch("engine",   DEFAULTS["engine"])
          pass   = options.fetch("password", DEFAULTS["password"])
          host   = options.fetch("host",     DEFAULTS["host"])
          port   = options.fetch("port",     DEFAULTS["port"])
          prefix = options.fetch("prefix",   DEFAULTS["prefix"])
          types  = options.fetch("types",    DEFAULTS["types"])

          db = if engine == "postgresql"
                 Sequel.postgres(dbname, :user => user, :password => pass, :host => host, :encoding => "utf8")
               else
                 Sequel.mysql2(dbname, :user => user, :password => pass, :host => host, :port => port, :encoding => "utf8")
               end

          query = build_query(prefix, types, engine)

          conf = Jekyll.configuration({})
          src_dir = conf["source"]

          dirs = {
            :_aliases => src_dir,
            :_posts   => File.join(src_dir, "_posts").to_s,
            :_drafts  => File.join(src_dir, "_drafts").to_s,
            :_layouts => Jekyll.sanitized_path(src_dir, conf["layouts_dir"].to_s),
          }

          dirs.each do |_key, dir|
            FileUtils.mkdir_p dir
          end

          # Create the refresh layout
          # Change the refresh url if you customized your permalink config
          File.open(File.join(dirs[:_layouts], "refresh.html"), "w") do |f|
            f.puts <<~HTML
              <!DOCTYPE html>
              <html>
              <head>
              <meta http-equiv="content-type" content="text/html; charset=utf-8" />
              <meta http-equiv="refresh" content="0;url={{ page.refresh_to_post_id }}.html" />
              <link rel="canonical" href="{{ page.refresh_to_post_id }}.html" />
              </head>
              </html>
            HTML
          end

          db[query].each do |post|
            # Get required fields
            data, content = post_data(post)

            data["layout"] = post[:type]
            title = data["title"] = post[:title].strip.force_encoding("UTF-8")
            time = data["created"] = post[:created]

            # Get the relevant fields as a hash and delete empty fields
            data = data.delete_if { |_k, v| v.nil? || v == "" }.each_pair do |_k, v|
              v.is_a?(String) ? v.force_encoding("UTF-8") : v
            end

            # Construct a Jekyll compatible file name
            is_published = post[:status] == 1
            node_id = post[:nid]
            dir = is_published ? dirs[:_posts] : dirs[:_drafts]
            slug = title.strip.downcase.gsub(%r!(&|&amp;)!, " and ").gsub(%r![\s\.\/\\]!, "-").gsub(%r![^\w-]!, "").gsub(%r![-_]{2,}!, "-").gsub(%r!^[-_]!, "").gsub(%r![-_]$!, "")
            filename = Time.at(time).to_datetime.strftime("%Y-%m-%d-") + slug + ".md"

            # Write out the data and content to file
            File.open("#{dir}/#{filename}", "w") do |f|
              f.puts data.to_yaml
              f.puts "---"
              f.puts content
            end

            # Make a file to redirect from the old Drupal URL
            next unless is_published

            alias_query = aliases_query(prefix)
            type = post[:type]

            aliases_type = db[alias_query, "#{type}/#{node_id}"].all
            aliases_node = db[alias_query, "node/#{node_id}"].all
            aliases = aliases_type.concat aliases_node

            aliases.push(:alias => "#{type}/#{node_id}")
            aliases.push(:alias => "node/#{node_id}")

            aliases.each do |url_alias|
              redirect_prefix = ""
              categories = data["categories"]
              unless categories.nil? || categories.length.zero?
                first_category = categories[0]
                redirect_prefix = "#{first_category}/"
              end

              partition = url_alias[:alias].rpartition("/")
              dir = ""
              file = partition.last

              if partition.first.length.positive?
                dir = "#{partition.first}/"
                FileUtils.mkdir_p "#{dirs[:_aliases]}/#{dir}"
              end

              File.open("#{dirs[:_aliases]}/#{dir}#{file}.md", "w") do |f|
                f.puts "---"
                f.puts "layout: refresh"
                f.puts "permalink: #{dir}#{file}/"
                f.puts "refresh_to_post_id: /#{redirect_prefix}#{Time.at(time).to_datetime.strftime("%Y/%m/%d/") + slug}"
                f.puts "---"
              end
            end
          end
        end
require_deps() click to toggle source
# File lib/jekyll-import/importers/drupal_common.rb, line 38
def require_deps
  JekyllImport.require_with_fallback(%w(
    rubygems
    sequel
    mysql2
    pg
    fileutils
    safe_yaml
  ))
end
specify_options(c) click to toggle source
# File lib/jekyll-import/importers/drupal_common.rb, line 25
def specify_options(c)
  c.option "dbname",   "--dbname DB",                 "Database name"
  c.option "user",     "--user USER",                 "Database user name"
  c.option "engine",   "--engine [mysql|postgresql]", "Database engine (default: #{DEFAULTS["engine"].inspect})"
  c.option "password", "--password PW",               "Database user's password (default: #{DEFAULTS["password"].inspect})"
  c.option "host",     "--host HOST",                 "Database host name (default: #{DEFAULTS["host"].inspect})"
  c.option "port",     "--port PORT",                 "Database port name (default: #{DEFAULTS["port"].inspect})"
  c.option "prefix",   "--prefix PREFIX",             "Table prefix name (default: #{DEFAULTS["prefix"].inspect})"

  c.option "types",    "--types TYPE1[,TYPE2[,TYPE3...]]", Array,
           "The Drupal content types to be imported  (default: #{DEFAULTS["types"].join(",")})"
end