jekyll-import 0.21.0 → 0.23.0

Sign up to get free protection for your applications and to get access to all the features.
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,