jekyll-import 0.21.0 → 0.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e0098ade7230382d4787c65ab3c17607680119727e1e9cdca587274d94e3e084
4
- data.tar.gz: 8f1050dfa7170aa7b08462c0132ab959ffdcda31e8c469929ce123aecb64909a
3
+ metadata.gz: 6fcccee7603179ae5818e0ba75bb5ad0f0abafdedd2f9f214347d02634683ed1
4
+ data.tar.gz: 8a1852ed040f027a25cc97c318445b6782aa1134917dc4823f72e073c86fdbcc
5
5
  SHA512:
6
- metadata.gz: f32b5ac48f88293a4703c7ece13d4a9886c598b4491fa9e8b750b02f4dfab405291c095355885f823a9b23551bc69e73015487371daa9fb6a9db7ec4783b88f0
7
- data.tar.gz: 0ba737a7d8ff767eb1bcce6bffa8af357d6c66793b36e682edfcce05245e21dd0a12d5a3d250118ae9b00dc40857db50884d2365e2419a86efce7d97e0ac52af
6
+ metadata.gz: c52bfbe4d79d920dadcceccc0cfae985c85219befd093cda8d63f6e8604e99da9823604413814d286061c7a5b14da74b17f92ed27211e4e4cd51c15385e5fdcd
7
+ data.tar.gz: 3c5f1a75535b1e3ffdb274641ab17724e8b5587a1e266a02dd9b3a334954fe45e2dd8f99a69712e942ac86a9f987fa73a481248a3cba907ad42dc55ef0a8fecd
data/.rubocop.yml ADDED
@@ -0,0 +1,17 @@
1
+ inherit_from: .rubocop_todo.yml
2
+
3
+ require: rubocop-jekyll
4
+ inherit_gem:
5
+ rubocop-jekyll: .rubocop.yml
6
+
7
+ AllCops:
8
+ TargetRubyVersion: 2.4
9
+ Exclude:
10
+ - docs/**/*
11
+ - script/**/*
12
+ - test/**/*
13
+ - vendor/**/*
14
+ - Rakefile
15
+ Style/MutableConstant:
16
+ Exclude:
17
+ - lib/jekyll-import/importers/typo.rb
data/README.markdown CHANGED
@@ -1,6 +1,7 @@
1
1
  # jekyll-import
2
2
 
3
- [![Build Status](https://travis-ci.org/jekyll/jekyll-import.svg?branch=master)](https://travis-ci.org/jekyll/jekyll-import)
3
+ [![Gem Version](https://img.shields.io/gem/v/jekyll-import.svg)](https://rubygems.org/gems/jekyll-import)
4
+ [![Continuous Integration](https://github.com/jekyll/jekyll-import/actions/workflows/ci.yml/badge.svg)](https://github.com/jekyll/jekyll-import/actions/workflows/ci.yml)
4
5
 
5
6
  The new __Jekyll__ command for importing from various blogs to Jekyll format.
6
7
 
@@ -11,7 +12,7 @@ The new __Jekyll__ command for importing from various blogs to Jekyll format.
11
12
  ### Jekyll v2.x and higher
12
13
 
13
14
  1. Install the _rubygem_ with `gem install jekyll-import`.
14
- 2. Run `jekyll import IMPORTER [options]`
15
+ 2. Run `jekyll-import IMPORTER [options]`
15
16
 
16
17
  ### Jekyll v1.x
17
18
 
data/exe/jekyll-import ADDED
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ STDOUT.sync = true
5
+
6
+ $LOAD_PATH.unshift File.expand_path("../lib", __dir__)
7
+
8
+ require 'jekyll-import'
9
+ require 'jekyll/commands/import'
10
+ require 'mercenary'
11
+
12
+ Mercenary.program(:jekyll_import) do |p|
13
+ p.version JekyllImport::VERSION
14
+ p.description "Import from various blogs to Jekyll format."
15
+ p.syntax "jekyll-import <blog_engine> [options]"
16
+
17
+ # Create all the subcommands for the importers.
18
+ JekyllImport.add_importer_commands(p)
19
+
20
+ p.action do |args, _|
21
+ if args.empty?
22
+ Jekyll.logger.error "An importer subcommand is required."
23
+ puts p
24
+ abort
25
+ else
26
+ subcommand = args.first
27
+ unless p.has_command? subcommand
28
+ Jekyll.logger.abort_with "fatal: 'jekyll-import #{args.first}'" \
29
+ " could not be found."
30
+ end
31
+ end
32
+ end
33
+ end
@@ -39,7 +39,7 @@ module Jekyll
39
39
  if args.empty?
40
40
  Jekyll.logger.warn "You must specify an importer."
41
41
  Jekyll.logger.info "Valid options are:"
42
- importers.each { |i| Jekyll.logger.info "*", i.to_s }
42
+ importers.sort.each { |i| Jekyll.logger.info "*", i.to_s }
43
43
  end
44
44
  end
45
45
  end
@@ -5,9 +5,9 @@ module JekyllImport
5
5
  class Blogger < Importer
6
6
  def self.specify_options(c)
7
7
  c.option "source", "--source NAME", "The XML file (blog-MM-DD-YYYY.xml) path to import"
8
- c.option "no-blogger-info", "--no-blogger-info", "not to leave blogger-URL info (id and old URL) in the front matter (default: false)"
8
+ c.option "no-blogger-info", "--no-blogger-info", "not to leave blogger-URL info (id and old URL) in the front matter. (default: false)"
9
9
  c.option "replace-internal-link", "--replace-internal-link", "replace internal links using the post_url liquid tag. (default: false)"
10
- c.option "comments", "--comments", "import comments to _comments collection"
10
+ c.option "comments", "--comments", "import comments to _comments collection. (default: false)"
11
11
  end
12
12
 
13
13
  def self.validate(options)
@@ -194,7 +194,7 @@ module JekyllImport
194
194
 
195
195
  FileUtils.mkdir_p(target_dir)
196
196
 
197
- file_name = URI.decode("#{post_data[:filename]}.html")
197
+ file_name = URI::DEFAULT_PARSER.unescape("#{post_data[:filename]}.html")
198
198
  File.open(File.join(target_dir, file_name), "w") do |f|
199
199
  f.flock(File::LOCK_EX)
200
200
 
@@ -12,8 +12,8 @@ module JekyllImport
12
12
  end
13
13
 
14
14
  def self.specify_options(c)
15
- c.option "file", "--file NAME", 'The CSV file to import (default: "posts.csv")'
16
- c.option "no-front-matter", "--no-front-matter", "Do not add the default front matter to the post body"
15
+ c.option "file", "--file NAME", "The CSV file to import. (default: 'posts.csv')"
16
+ c.option "no-front-matter", "--no-front-matter", "Do not add the default front matter to the post body. (default: false)"
17
17
  end
18
18
 
19
19
  # Reads a csv with title, permalink, body, published_at, and filter.
@@ -1,121 +1,180 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Tested with dotClear 2.1.5
4
3
  module JekyllImport
5
4
  module Importers
6
5
  class Dotclear < Importer
7
- def self.specify_options(c)
8
- c.option "datafile", "--datafile PATH", "dotClear export file"
9
- c.option "mediafolder", "--mediafolder PATH", "dotClear media export folder (media.zip inflated)"
10
- end
6
+ class << self
7
+ def specify_options(c)
8
+ c.option "datafile", "--datafile PATH", "Dotclear export file."
9
+ c.option "mediafolder", "--mediafolder DIR", "Dotclear media export folder (unpacked media.zip)."
10
+ end
11
11
 
12
- def self.require_deps
13
- JekyllImport.require_with_fallback(%w(
14
- rubygems
15
- fileutils
16
- safe_yaml
17
- date
18
- active_support
19
- active_support/core_ext/string/inflections
20
- csv
21
- pp
22
- ))
23
- end
12
+ def require_deps
13
+ JekyllImport.require_with_fallback(%w())
14
+ end
24
15
 
25
- def self.validate(opts)
26
- abort "Specify a data file !" if opts["datafile"].nil? || opts["datafile"].empty?
27
- abort "Specify a media folder !" if opts["mediafolder"].nil? || opts["mediafolder"].empty?
28
- end
16
+ def validate(opts)
17
+ file_path = opts["datafile"]
18
+ log_undefined_flag_error("datafile") if file_path.nil? || file_path.empty?
29
19
 
30
- def self.extract_headers_section(str)
31
- str[1..-2].split(" ")[1].split(",")
32
- end
33
-
34
- def self.extract_data_section(str)
35
- str.gsub(%r!^"!, "").gsub(%r!"$!, "").split('","')
36
- end
20
+ file_path = File.expand_path(file_path)
21
+ if File.open(file_path, "rb", &:readline).start_with?("///DOTCLEAR|")
22
+ @data = read_export(file_path)
23
+ Jekyll.logger.info "Export File:", file_path
24
+ else
25
+ Jekyll.logger.abort_with "Import Error:", "#{file_path.inspect} is not a valid Dotclear export file!"
26
+ end
37
27
 
38
- def self.process(opts)
39
- options = {
40
- :datafile => opts.fetch("datafile", ""),
41
- :mediafolder => opts.fetch("mediafolder", ""),
42
- }
28
+ assets = @data["media"]
29
+ return if !assets || assets.empty?
43
30
 
44
- FileUtils.mkdir_p("_posts")
45
- FileUtils.mkdir_p("_drafts")
31
+ Jekyll.logger.info "", "Media files detected in export data."
46
32
 
47
- type_data = ""
48
- headers = {}
49
- posts_and_drafts = {}
50
- keywords = {}
33
+ media_dir = opts["mediafolder"]
34
+ log_undefined_flag_error("mediafolder") if media_dir.nil? || media_dir.empty?
51
35
 
52
- File.readlines(options[:datafile]).each do |lineraw|
53
- line = lineraw.strip.gsub(%r!\n$!, "")
36
+ media_dir = File.expand_path(media_dir)
37
+ log_invalid_media_dir_error(media_dir) if !File.directory?(media_dir) || Dir.empty?(media_dir)
38
+ end
54
39
 
55
- next if line.empty?
40
+ def process(opts)
41
+ import_posts
42
+ import_assets(opts["mediafolder"])
43
+ Jekyll.logger.info "", "and, done!"
44
+ end
56
45
 
57
- if line.start_with?("[") # post | media \ meta | comment...
58
- type_data = line.split(" ").first[1..-1]
59
- headers[type_data] = extract_headers_section(line)
60
- next
46
+ private
47
+
48
+ # Parse backup sections into a Hash of arrays.
49
+ #
50
+ # Each section is of following shape:
51
+ #
52
+ # [key alpha,beta,gamma,...]
53
+ # lorem,ipsum,dolor,...
54
+ # red,blue,green,...
55
+ #
56
+ # Returns Hash of shape:
57
+ #
58
+ # {key => [{alpha => lorem,...}, {alpha => red,...}]}
59
+ #
60
+ def read_export(file)
61
+ ignored_sections = %w(category comment link setting)
62
+
63
+ File.read(file, :encoding => "utf-8").split("\n\n").each_with_object({}) do |section, data|
64
+ next unless %r!^\[(?<key>.*?) (?<header>.*)\]\n(?<rows>.*)!m =~ section
65
+ next if ignored_sections.include?(key)
66
+
67
+ headers = header.split(",")
68
+
69
+ data[key] = rows.each_line.with_object([]) do |line, bucket|
70
+ bucket << headers.zip(sanitize_line!(line)).to_h
71
+ end
72
+
73
+ data
61
74
  end
75
+ end
62
76
 
63
- elts = extract_data_section(line)
64
-
65
- if type_data == "post"
66
- draft = (elts[headers[type_data].index("post_status")] != "1")
77
+ def register_post_tags
78
+ @data["meta"].each_with_object({}) do |entry, tags|
79
+ next unless entry["meta_type"] == "tag"
67
80
 
68
- date_str = elts[headers[type_data].index("post_creadt")]
69
- date_blank = (date_str.nil? || date_str.empty?)
70
- date_str_formatted = date_blank ? Date.today : Date.parse(date_str).strftime("%Y-%m-%d")
71
- title_param = elts[headers[type_data].index("post_title")].to_s.parameterize
81
+ post_id = entry["post_id"]
82
+ tags[post_id] ||= []
83
+ tags[post_id] << entry["meta_id"]
84
+ end
85
+ end
72
86
 
73
- content = elts[headers[type_data].index("post_content_xhtml")].to_s
74
- content = content.gsub('\"', '"').gsub('\n', "\n").gsub("/public/", "/assets/images/")
87
+ def log_undefined_flag_error(label)
88
+ Jekyll.logger.abort_with "Import Error:", "--#{label} flag cannot be undefined, null or empty!"
89
+ end
75
90
 
76
- filepath = File.join(Dir.pwd, (draft ? "_drafts" : "_posts"), "#{date_str_formatted}-#{title_param}.html")
91
+ def log_invalid_media_dir_error(media_dir)
92
+ Jekyll.logger.error "Import Error:", "--mediafolder should be a non-empty directory."
93
+ Jekyll.logger.abort_with "", "Please check #{media_dir.inspect}."
94
+ end
77
95
 
78
- entire_content_file = <<~POST_FILE
79
- ---
80
- layout: post
81
- title: "#{elts[headers[type_data].index("post_title")]}"
82
- date: #{elts[headers[type_data].index("post_creadt")]} +0100
83
- tags: ABC
84
- ---
96
+ def sanitize_line!(line)
97
+ line.strip!
98
+ line.split('","').tap do |items|
99
+ items[0].delete_prefix!('"')
100
+ items[-1].delete_suffix!('"')
101
+ end
102
+ end
85
103
 
86
- #{content}
87
- POST_FILE
104
+ # -
88
105
 
89
- posts_and_drafts[elts[headers[type_data].index("post_id")]] = { :path => filepath, :content => entire_content_file }
90
- elsif type_data == "media"
91
- elts[headers[type_data].index("media_title")]
92
- mediafilepath = elts[headers[type_data].index("media_file")]
106
+ REPLACE_MAP = {
107
+ '\"' => '"',
108
+ '\r\n' => "\n",
109
+ '\n' => "\n",
110
+ "/dotclear/public/" => "/assets/dotclear/",
111
+ "/public/" => "/assets/dotclear/",
112
+ }.freeze
93
113
 
94
- src_path = File.join(options[:mediafolder], mediafilepath)
95
- dst_path = File.join(Dir.pwd, "assets", "images", mediafilepath.to_s)
114
+ REPLACE_RE = Regexp.union(REPLACE_MAP.keys)
96
115
 
97
- FileUtils.mkdir_p(File.dirname(dst_path))
98
- FileUtils.cp(src_path, dst_path)
99
- elsif type_data == "meta"
100
- keywords[elts[headers[type_data].index("post_id")]] ||= []
101
- keywords[elts[headers[type_data].index("post_id")]] << elts[headers[type_data].index("meta_id")]
102
- elsif type_data == "link"
116
+ private_constant :REPLACE_MAP, :REPLACE_RE
103
117
 
104
- elsif type_data == "setting"
118
+ # -
105
119
 
106
- elsif type_data == "comment"
120
+ def adjust_post_contents!(content)
121
+ content.strip!
122
+ content.gsub!(REPLACE_RE, REPLACE_MAP)
123
+ content
124
+ end
107
125
 
126
+ def import_posts
127
+ tags = register_post_tags
128
+ posts = @data["post"]
129
+
130
+ FileUtils.mkdir_p("_drafts") unless posts.empty?
131
+ Jekyll.logger.info "Importing posts.."
132
+
133
+ posts.each do |post|
134
+ date, title = post.values_at("post_creadt", "post_title")
135
+ path = File.join("_drafts", Date.parse(date).strftime("%Y-%m-%d-") + Jekyll::Utils.slugify(title) + ".html")
136
+
137
+ excerpt = adjust_post_contents!(post["post_excerpt_xhtml"].to_s)
138
+ excerpt = nil if excerpt.empty?
139
+
140
+ # Unlike the paradigm in Jekyll-generated HTML, `post_content_xhtml` in the export data
141
+ # doesn't begin with `post_excerpt_xhtml`.
142
+ # Instead of checking whether the excerpt content exists elsewhere in the exported content
143
+ # string, always prepend excerpt onto content with an empty line in between.
144
+ content = [excerpt, post["post_content_xhtml"]].tap(&:compact!).join("\n\n")
145
+
146
+ front_matter_data = {
147
+ "layout" => "post",
148
+ "title" => title,
149
+ "date" => date,
150
+ "lang" => post["post_lang"],
151
+ "tags" => tags[post["post_id"]],
152
+ "original_url" => post["post_url"], # URL as included in the export-file.
153
+ "excerpt" => excerpt,
154
+ }.tap(&:compact!)
155
+
156
+ Jekyll.logger.info "Creating:", path
157
+ File.write(path, "#{YAML.dump(front_matter_data)}---\n\n#{adjust_post_contents!(content)}\n")
108
158
  end
109
159
  end
110
160
 
111
- # POST-process : Change media path in posts and drafts
112
- posts_and_drafts.each do |post_id, hsh|
113
- keywords_str = keywords[post_id].to_a.join(", ")
114
- content_file = hsh[:content]
115
- content_file = content_file.gsub("tags: ABC", "tags: [#{keywords_str}]")
116
-
117
- File.open(hsh[:path], "wb") do |f|
118
- f.write(content_file)
161
+ def import_assets(src_dir)
162
+ assets = @data["media"]
163
+ FileUtils.mkdir_p("assets/dotclear") if assets && !assets.empty?
164
+ Jekyll.logger.info "Importing assets.."
165
+
166
+ assets.each do |asset|
167
+ file_path = File.join(src_dir, asset["media_file"])
168
+ if File.exist?(file_path)
169
+ dest_path = File.join("assets/dotclear", asset["media_file"])
170
+ FileUtils.mkdir_p(File.dirname(dest_path))
171
+
172
+ Jekyll.logger.info "Copying:", file_path
173
+ Jekyll.logger.info "To:", dest_path
174
+ FileUtils.cp_r file_path, dest_path
175
+ else
176
+ Jekyll.logger.info "Not found:", file_path
177
+ end
119
178
  end
120
179
  end
121
180
  end
@@ -16,16 +16,16 @@ module JekyllImport
16
16
  DEFAULTS = {
17
17
  "engine" => "mysql",
18
18
  "password" => "",
19
- "host" => "localhost",
19
+ "host" => "127.0.0.1",
20
20
  "prefix" => "",
21
21
  "port" => "3306",
22
22
  "types" => %w(blog story article),
23
23
  }.freeze
24
24
 
25
25
  def specify_options(c)
26
- c.option "engine", "--engine [mysql|postgresql]", "Database engine (default: #{DEFAULTS["engine"].inspect})"
27
26
  c.option "dbname", "--dbname DB", "Database name"
28
27
  c.option "user", "--user USER", "Database user name"
28
+ c.option "engine", "--engine [mysql|postgresql]", "Database engine (default: #{DEFAULTS["engine"].inspect})"
29
29
  c.option "password", "--password PW", "Database user's password (default: #{DEFAULTS["password"].inspect})"
30
30
  c.option "host", "--host HOST", "Database host name (default: #{DEFAULTS["host"].inspect})"
31
31
  c.option "port", "--port PORT", "Database port name (default: #{DEFAULTS["port"].inspect})"
@@ -47,9 +47,9 @@ module JekyllImport
47
47
  end
48
48
 
49
49
  def process(options)
50
- engine = options.fetch("engine", DEFAULTS["engine"])
51
50
  dbname = options.fetch("dbname")
52
51
  user = options.fetch("user")
52
+ engine = options.fetch("engine", DEFAULTS["engine"])
53
53
  pass = options.fetch("password", DEFAULTS["password"])
54
54
  host = options.fetch("host", DEFAULTS["host"])
55
55
  port = options.fetch("port", DEFAULTS["port"])
@@ -10,12 +10,12 @@ module JekyllImport
10
10
  end
11
11
 
12
12
  def self.specify_options(c)
13
- c.option "dbname", "--dbname", "Database name"
14
- c.option "user", "--user", "Database user name"
15
- c.option "password", "--password", "Database user's password (default: '')"
16
- c.option "host", "--host", "Database host name"
17
- c.option "section", "--section", "Table prefix name"
18
- c.option "prefix", "--prefix", "Table prefix name"
13
+ c.option "dbname", "--dbname", "Database name."
14
+ c.option "user", "--user", "Database user name."
15
+ c.option "password", "--password", "Database user's password. (default: '')"
16
+ c.option "host", "--host", "Database host name. (default: 'localhost')"
17
+ c.option "section", "--section", "Section ID. (default: '1')"
18
+ c.option "prefix", "--prefix", "Table prefix name. (default: 'jos_')"
19
19
  end
20
20
 
21
21
  def self.require_deps
@@ -32,7 +32,7 @@ module JekyllImport
32
32
  dbname = options.fetch("dbname")
33
33
  user = options.fetch("user")
34
34
  pass = options.fetch("password", "")
35
- host = options.fetch("host", "localhost")
35
+ host = options.fetch("host", "127.0.0.1")
36
36
  section = options.fetch("section", "1")
37
37
  table_prefix = options.fetch("prefix", "jos_")
38
38
 
@@ -20,10 +20,10 @@ module JekyllImport
20
20
  end
21
21
 
22
22
  def self.specify_options(c)
23
- c.option "dbname", "--dbname", "Database name"
24
- c.option "user", "--user", "Database name"
25
- c.option "password", "--password", 'Database name (default: "")'
26
- c.option "host", "--host", "Database name"
23
+ c.option "dbname", "--dbname", "Database name."
24
+ c.option "user", "--user", "User name."
25
+ c.option "password", "--password", "Database password. (default: '')"
26
+ c.option "host", "--host", "Database host name. (default: 'localhost')"
27
27
  end
28
28
 
29
29
  def self.require_deps
@@ -10,13 +10,13 @@ module JekyllImport
10
10
  end
11
11
 
12
12
  def self.specify_options(c)
13
- c.option "dbname", "--dbname", "Database name"
14
- c.option "user", "--user", "Database user name"
15
- c.option "password", "--password", "Database user's password (default: '')"
16
- c.option "host", "--host", "Database host name"
17
- c.option "port", "--port", "Database port"
18
- c.option "section", "--section", "Table prefix name"
19
- c.option "prefix", "--prefix", "Table prefix name"
13
+ c.option "dbname", "--dbname", "Database name."
14
+ c.option "user", "--user", "Database user name."
15
+ c.option "password", "--password", "Database user's password. (default: '')"
16
+ c.option "host", "--host", "Database host name. (default: 'localhost')"
17
+ c.option "port", "--port", "Database port. (default: '3306')"
18
+ c.option "section", "--section", "Section ID. (default: '1')"
19
+ c.option "prefix", "--prefix", "Table prefix name. (default: 'jos_')"
20
20
  end
21
21
 
22
22
  def self.require_deps
@@ -33,7 +33,7 @@ module JekyllImport
33
33
  dbname = options.fetch("dbname")
34
34
  user = options.fetch("user")
35
35
  pass = options.fetch("password", "")
36
- host = options.fetch("host", "localhost")
36
+ host = options.fetch("host", "127.0.0.1")
37
37
  port = options.fetch("port", 3306).to_i
38
38
  section = options.fetch("section", "1")
39
39
  table_prefix = options.fetch("prefix", "jos_")
@@ -10,13 +10,13 @@ module JekyllImport
10
10
  end
11
11
 
12
12
  def self.specify_options(c)
13
- c.option "dbname", "--dbname", "Database name"
14
- c.option "user", "--user", "Database user name"
15
- c.option "password", "--password", "Database user's password (default: '')"
16
- c.option "host", "--host", "Database host name"
17
- c.option "port", "--port", "Database port"
18
- c.option "category", "--category", "ID of the category"
19
- c.option "prefix", "--prefix", "Table prefix name"
13
+ c.option "dbname", "--dbname", "Database name."
14
+ c.option "user", "--user", "Database user name."
15
+ c.option "password", "--password", "Database user's password. (default: '')"
16
+ c.option "host", "--host", "Database host name. (default: 'localhost')"
17
+ c.option "port", "--port", "Database port. (default: '3306')"
18
+ c.option "category", "--category", "ID of the category. (default: '0')"
19
+ c.option "prefix", "--prefix", "Table prefix name. (default: 'jos_')"
20
20
  end
21
21
 
22
22
  def self.require_deps
@@ -33,7 +33,7 @@ module JekyllImport
33
33
  dbname = options.fetch("dbname")
34
34
  user = options.fetch("user")
35
35
  pass = options.fetch("password", "")
36
- host = options.fetch("host", "localhost")
36
+ host = options.fetch("host", "127.0.0.1")
37
37
  port = options.fetch("port", 3306).to_i
38
38
  cid = options.fetch("category", 0)
39
39
  table_prefix = options.fetch("prefix", "jos_")
@@ -12,10 +12,10 @@ module JekyllImport
12
12
  end
13
13
 
14
14
  def self.specify_options(c)
15
- c.option "file", "--file FILENAME", 'Journal file (default: "~/journal.txt")'
16
- c.option "time_format", "--time_format FORMAT", 'Time format of your journal (default: "%Y-%m-%d %H:%M")'
17
- c.option "extension", "--extension EXT", 'Output extension (default: "md")'
18
- c.option "layout", "--layout NAME", 'Output post layout (default: "post")'
15
+ c.option "file", "--file FILENAME", "Journal file. (default: '~/journal.txt')"
16
+ c.option "time_format", "--time_format FORMAT", "Time format of your journal. (default: '%Y-%m-%d %H:%M')"
17
+ c.option "extension", "--extension EXT", "Output extension. (default: 'md')"
18
+ c.option "layout", "--layout NAME", "Output post layout. (default: 'post')"
19
19
  end
20
20
 
21
21
  # Reads a jrnl file and creates a new post for each entry
@@ -28,7 +28,7 @@ module JekyllImport
28
28
  end
29
29
 
30
30
  def self.specify_options(c)
31
- c.option "marley_data_dir", "--marley_data_dir DIR", "The dir containing your marley data"
31
+ c.option "marley_data_dir", "--marley_data_dir DIR", "The dir containing your marley data."
32
32
  end
33
33
 
34
34
  def self.process(options)
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JekyllImport
4
+ module Importers
5
+ class Medium < Importer
6
+ def self.specify_options(c)
7
+ c.option "username", "--username NAME", "Medium username"
8
+ c.option "canonical_link", "--canonical_link", "Copy original link as canonical_url to post (default: false)"
9
+ c.option "render_audio", "--render_audio", "Render <audio> element in posts for the enclosure URLs (default: false)"
10
+ end
11
+
12
+ def self.validate(options)
13
+ abort "Missing mandatory option --username." if options["username"].nil?
14
+ end
15
+
16
+ def self.require_deps
17
+ Importers::RSS.require_deps
18
+ end
19
+
20
+ # Medium posts and associated metadata are exported as an RSS Feed. Hence invoke our RSS Importer to create the
21
+ # Jekyll source directory.
22
+ #
23
+ # "Tags" attached to a Medium post are exported under the markup `<item><category>...</category></item>` in the
24
+ # export feed. Therefore, configure the RSS Importer to always look for tags in the `<category></category>` field
25
+ # of an RSS item.
26
+ def self.process(options)
27
+ Importers::RSS.process({
28
+ "source" => "https://medium.com/feed/@#{options.fetch("username")}",
29
+ "render_audio" => options.fetch("render_audio", false),
30
+ "canonical_link" => options.fetch("canonical_link", false),
31
+ "extract_tags" => "category",
32
+ })
33
+ end
34
+ end
35
+ end
36
+ end
@@ -14,7 +14,7 @@ module JekyllImport
14
14
  COPY jekyll TO STDOUT WITH CSV HEADER;
15
15
  ROLLBACK;
16
16
  SQL
17
- command = %(psql -h #{c[:host] || "localhost"} -c "#{sql.strip}" #{c[:database]} #{c[:username]} -o #{c[:filename] || "posts.csv"})
17
+ command = %(psql -h #{c[:host] || "127.0.0.1"} -c "#{sql.strip}" #{c[:database]} #{c[:username]} -o #{c[:filename] || "posts.csv"})
18
18
  Jekyll.logger.info "Executing:", command
19
19
  `#{command}`
20
20
  CSV.process
@@ -40,7 +40,7 @@ module JekyllImport
40
40
  c.option "dbname", "--dbname DB", "Database name"
41
41
  c.option "user", "--user USER", "Database user name"
42
42
  c.option "password", "--password PW", "Database user's password (default: '')"
43
- c.option "host", "--host HOST", 'Database host name (default: "localhost")'
43
+ c.option "host", "--host HOST", "Database host name (default: 'localhost')"
44
44
  end
45
45
 
46
46
  # This query will pull blog posts from all entries across all blogs. If
@@ -61,7 +61,7 @@ module JekyllImport
61
61
  dbname = options.fetch("dbname")
62
62
  user = options.fetch("user")
63
63
  pass = options.fetch("password", "")
64
- host = options.fetch("host", "localhost")
64
+ host = options.fetch("host", "127.0.0.1")
65
65
 
66
66
  db = Sequel.mysql2(dbname, :user => user,
67
67
  :password => pass,