jekyll-import 0.12.0 → 0.13.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 +4 -4
- data/lib/jekyll-import.rb +10 -8
- data/lib/jekyll-import/importer.rb +1 -1
- data/lib/jekyll-import/importers.rb +1 -1
- data/lib/jekyll-import/importers/behance.rb +20 -20
- data/lib/jekyll-import/importers/blogger.rb +108 -118
- data/lib/jekyll-import/importers/csv.rb +7 -7
- data/lib/jekyll-import/importers/drupal6.rb +5 -6
- data/lib/jekyll-import/importers/drupal7.rb +7 -13
- data/lib/jekyll-import/importers/drupal_common.rb +57 -59
- data/lib/jekyll-import/importers/easyblog.rb +30 -30
- data/lib/jekyll-import/importers/enki.rb +28 -29
- data/lib/jekyll-import/importers/ghost.rb +46 -33
- data/lib/jekyll-import/importers/google_reader.rb +9 -9
- data/lib/jekyll-import/importers/joomla.rb +32 -32
- data/lib/jekyll-import/importers/joomla3.rb +41 -39
- data/lib/jekyll-import/importers/jrnl.rb +16 -17
- data/lib/jekyll-import/importers/marley.rb +25 -26
- data/lib/jekyll-import/importers/mephisto.rb +26 -26
- data/lib/jekyll-import/importers/mt.rb +76 -75
- data/lib/jekyll-import/importers/posterous.rb +30 -29
- data/lib/jekyll-import/importers/rss.rb +13 -10
- data/lib/jekyll-import/importers/s9y.rb +16 -17
- data/lib/jekyll-import/importers/s9y_database.rb +98 -89
- data/lib/jekyll-import/importers/textpattern.rb +18 -17
- data/lib/jekyll-import/importers/tmp.rb +0 -0
- data/lib/jekyll-import/importers/tumblr.rb +146 -143
- data/lib/jekyll-import/importers/typo.rb +31 -31
- data/lib/jekyll-import/importers/wordpress.rb +100 -100
- data/lib/jekyll-import/importers/wordpressdotcom.rb +70 -60
- data/lib/jekyll-import/util.rb +24 -24
- data/lib/jekyll-import/version.rb +1 -1
- data/lib/jekyll/commands/import.rb +32 -35
- metadata +14 -13
@@ -2,59 +2,58 @@ module JekyllImport
|
|
2
2
|
module Importers
|
3
3
|
class Marley < Importer
|
4
4
|
def self.validate(options)
|
5
|
-
if options[
|
5
|
+
if options["marley_data_dir"].nil?
|
6
6
|
Jekyll.logger.abort_with "Missing mandatory option --marley_data_dir."
|
7
7
|
else
|
8
|
-
unless File.directory?(options[
|
9
|
-
raise ArgumentError, "marley dir '#{options[
|
8
|
+
unless File.directory?(options["marley_data_dir"])
|
9
|
+
raise ArgumentError, "marley dir '#{options["marley_data_dir"]}' not found"
|
10
10
|
end
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
14
|
def self.regexp
|
15
|
-
{ :id
|
16
|
-
:title
|
17
|
-
:title_with_date =>
|
18
|
-
:published_on
|
19
|
-
:perex
|
20
|
-
:meta
|
21
|
-
}
|
15
|
+
{ :id => %r!^\d{0,4}-{0,1}(.*)$!,
|
16
|
+
:title => %r!^#\s*(.*)\s+$!,
|
17
|
+
:title_with_date => %r!^#\s*(.*)\s+\(([0-9\/]+)\)$!,
|
18
|
+
:published_on => %r!.*\s+\(([0-9\/]+)\)$!,
|
19
|
+
:perex => %r!^([^\#\n]+\n)$!,
|
20
|
+
:meta => %r!^\{\{\n(.*)\}\}\n$!mi, } # Multiline Regexp
|
22
21
|
end
|
23
22
|
|
24
23
|
def self.require_deps
|
25
|
-
JekyllImport.require_with_fallback(%w
|
24
|
+
JekyllImport.require_with_fallback(%w(
|
26
25
|
fileutils
|
27
26
|
safe_yaml
|
28
|
-
|
27
|
+
))
|
29
28
|
end
|
30
29
|
|
31
30
|
def self.specify_options(c)
|
32
|
-
c.option
|
31
|
+
c.option "marley_data_dir", "--marley_data_dir DIR", "The dir containing your marley data"
|
33
32
|
end
|
34
33
|
|
35
34
|
def self.process(options)
|
36
|
-
marley_data_dir = options.fetch(
|
35
|
+
marley_data_dir = options.fetch("marley_data_dir")
|
37
36
|
|
38
37
|
FileUtils.mkdir_p "_posts"
|
39
38
|
|
40
39
|
posts = 0
|
41
40
|
Dir["#{marley_data_dir}/**/*.txt"].each do |f|
|
42
|
-
next unless File.
|
41
|
+
next unless File.exist?(f)
|
43
42
|
|
44
|
-
#copied over from marley's app/lib/post.rb
|
43
|
+
# copied over from marley's app/lib/post.rb
|
45
44
|
file_content = File.read(f)
|
46
|
-
meta_content = file_content.slice!(
|
47
|
-
body = file_content.sub(
|
45
|
+
meta_content = file_content.slice!(self.regexp[:meta])
|
46
|
+
body = file_content.sub(self.regexp[:title], "").sub(self.regexp[:perex], "").strip
|
48
47
|
|
49
|
-
title = file_content.scan(
|
50
|
-
prerex = file_content.scan(
|
51
|
-
published_on = DateTime.parse(
|
52
|
-
meta =
|
53
|
-
meta[
|
54
|
-
meta[
|
48
|
+
title = file_content.scan(self.regexp[:title]).first.to_s.strip
|
49
|
+
prerex = file_content.scan(self.regexp[:perex]).first.to_s.strip
|
50
|
+
published_on = DateTime.parse(post[:published_on]) rescue File.mtime(File.dirname(f))
|
51
|
+
meta = meta_content ? YAML.safe_load(meta_content.scan(self.regexp[:meta]).to_s) : {}
|
52
|
+
meta["title"] = title
|
53
|
+
meta["layout"] = "post"
|
55
54
|
|
56
|
-
formatted_date = published_on.strftime(
|
57
|
-
post_name =
|
55
|
+
formatted_date = published_on.strftime("%Y-%m-%d")
|
56
|
+
post_name = File.dirname(f).split(%r!/!).last.gsub(%r!\A\d+-!, "")
|
58
57
|
|
59
58
|
name = "#{formatted_date}-#{post_name}"
|
60
59
|
File.open("_posts/#{name}.markdown", "w") do |f|
|
@@ -1,8 +1,8 @@
|
|
1
1
|
module JekyllImport
|
2
2
|
module Importers
|
3
3
|
class Mephisto < Importer
|
4
|
-
#Accepts a hash with database config variables, exports mephisto posts into a csv
|
5
|
-
#export PGPASSWORD if you must
|
4
|
+
# Accepts a hash with database config variables, exports mephisto posts into a csv
|
5
|
+
# export PGPASSWORD if you must
|
6
6
|
def self.postgres(c)
|
7
7
|
sql = <<-SQL
|
8
8
|
BEGIN;
|
@@ -12,14 +12,14 @@ module JekyllImport
|
|
12
12
|
COPY jekyll TO STDOUT WITH CSV HEADER;
|
13
13
|
ROLLBACK;
|
14
14
|
SQL
|
15
|
-
command = %
|
15
|
+
command = %(psql -h #{c[:host] || "localhost"} -c "#{sql.strip}" #{c[:database]} #{c[:username]} -o #{c[:filename] || "posts.csv"})
|
16
16
|
puts command
|
17
17
|
`#{command}`
|
18
18
|
CSV.process
|
19
19
|
end
|
20
20
|
|
21
21
|
def self.validate(options)
|
22
|
-
%w
|
22
|
+
%w(dbname user).each do |option|
|
23
23
|
if options[option].nil?
|
24
24
|
abort "Missing mandatory option --#{option}."
|
25
25
|
end
|
@@ -27,19 +27,20 @@ module JekyllImport
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def self.require_deps
|
30
|
-
JekyllImport.require_with_fallback(%w
|
30
|
+
JekyllImport.require_with_fallback(%w(
|
31
31
|
rubygems
|
32
32
|
sequel
|
33
|
+
mysql2
|
33
34
|
fastercsv
|
34
35
|
fileutils
|
35
|
-
|
36
|
+
))
|
36
37
|
end
|
37
38
|
|
38
39
|
def self.specify_options(c)
|
39
|
-
c.option
|
40
|
-
c.option
|
41
|
-
c.option
|
42
|
-
c.option
|
40
|
+
c.option "dbname", "--dbname DB", "Database name"
|
41
|
+
c.option "user", "--user USER", "Database user name"
|
42
|
+
c.option "password", "--password PW", "Database user's password (default: '')"
|
43
|
+
c.option "host", "--host HOST", 'Database host name (default: "localhost")'
|
43
44
|
end
|
44
45
|
|
45
46
|
# This query will pull blog posts from all entries across all blogs. If
|
@@ -54,18 +55,18 @@ module JekyllImport
|
|
54
55
|
WHERE user_id = 1 AND \
|
55
56
|
type = 'Article' AND \
|
56
57
|
published_at IS NOT NULL \
|
57
|
-
ORDER BY published_at"
|
58
|
+
ORDER BY published_at".freeze
|
58
59
|
|
59
60
|
def self.process(options)
|
60
|
-
dbname = options.fetch(
|
61
|
-
user = options.fetch(
|
62
|
-
pass = options.fetch(
|
63
|
-
host = options.fetch(
|
61
|
+
dbname = options.fetch("dbname")
|
62
|
+
user = options.fetch("user")
|
63
|
+
pass = options.fetch("password", "")
|
64
|
+
host = options.fetch("host", "localhost")
|
64
65
|
|
65
|
-
db = Sequel.
|
66
|
-
|
67
|
-
|
68
|
-
|
66
|
+
db = Sequel.mysql2(dbname, :user => user,
|
67
|
+
:password => pass,
|
68
|
+
:host => host,
|
69
|
+
:encoding => "utf8")
|
69
70
|
|
70
71
|
FileUtils.mkdir_p "_posts"
|
71
72
|
|
@@ -78,13 +79,13 @@ module JekyllImport
|
|
78
79
|
# Ideally, this script would determine the post format (markdown,
|
79
80
|
# html, etc) and create files with proper extensions. At this point
|
80
81
|
# it just assumes that markdown will be acceptable.
|
81
|
-
name = [date.year, date.month, date.day, slug].join(
|
82
|
+
name = [date.year, date.month, date.day, slug].join("-") + ".markdown"
|
82
83
|
|
83
84
|
data = {
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
85
|
+
"layout" => "post",
|
86
|
+
"title" => title.to_s,
|
87
|
+
"mt_id" => post[:entry_id],
|
88
|
+
}.delete_if { |_k, v| v.nil? || v == "" }.to_yaml
|
88
89
|
|
89
90
|
File.open("_posts/#{name}", "w") do |f|
|
90
91
|
f.puts data
|
@@ -92,8 +93,7 @@ module JekyllImport
|
|
92
93
|
f.puts content
|
93
94
|
end
|
94
95
|
end
|
95
|
-
|
96
96
|
end
|
97
97
|
end
|
98
98
|
end
|
99
|
-
end
|
99
|
+
end
|
@@ -1,44 +1,46 @@
|
|
1
1
|
module JekyllImport
|
2
2
|
module Importers
|
3
3
|
class MT < Importer
|
4
|
-
|
5
|
-
SUPPORTED_ENGINES = %{mysql postgres sqlite}
|
4
|
+
SUPPORTED_ENGINES = %(mysql postgres sqlite).freeze
|
6
5
|
|
7
6
|
STATUS_DRAFT = 1
|
8
7
|
STATUS_PUBLISHED = 2
|
9
|
-
MORE_CONTENT_SEPARATOR =
|
8
|
+
MORE_CONTENT_SEPARATOR = "<!--more-->".freeze
|
10
9
|
|
11
10
|
def self.default_options
|
12
11
|
{
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
12
|
+
"blog_id" => nil,
|
13
|
+
"categories" => true,
|
14
|
+
"dest_encoding" => "utf-8",
|
15
|
+
"src_encoding" => "utf-8",
|
16
|
+
"comments" => false,
|
18
17
|
}
|
19
18
|
end
|
20
19
|
|
21
20
|
def self.require_deps
|
22
|
-
JekyllImport.require_with_fallback(%w
|
21
|
+
JekyllImport.require_with_fallback(%w(
|
23
22
|
rubygems
|
24
23
|
sequel
|
24
|
+
sqlite3
|
25
|
+
mysql2
|
26
|
+
pg
|
25
27
|
fileutils
|
26
28
|
safe_yaml
|
27
|
-
|
29
|
+
))
|
28
30
|
end
|
29
31
|
|
30
32
|
def self.specify_options(c)
|
31
|
-
c.option
|
32
|
-
c.option
|
33
|
-
c.option
|
34
|
-
c.option
|
35
|
-
c.option
|
36
|
-
c.option
|
37
|
-
c.option
|
38
|
-
c.option
|
39
|
-
c.option
|
40
|
-
c.option
|
41
|
-
c.option
|
33
|
+
c.option "engine", "--engine ENGINE", "Database engine, (default: 'mysql', postgres also supported)"
|
34
|
+
c.option "dbname", "--dbname DB", "Database name"
|
35
|
+
c.option "user", "--user USER", "Database user name"
|
36
|
+
c.option "password", "--password PW", "Database user's password, (default: '')"
|
37
|
+
c.option "host", "--host HOST", 'Database host name (default: "localhost")'
|
38
|
+
c.option "port", "--port PORT", "Custom database port connect to (optional)"
|
39
|
+
c.option "blog_id", "--blog_id ID", "Specify a single Movable Type blog ID to import (default: all blogs)"
|
40
|
+
c.option "categories", "--categories", "If true, save post's categories in its YAML front matter. (default: true)"
|
41
|
+
c.option "src_encoding", "--src_encoding ENCODING", "Encoding of strings from database. (default: UTF-8)"
|
42
|
+
c.option "dest_encoding", "--dest_encoding ENCODING", "Encoding of output strings. (default: UTF-8)"
|
43
|
+
c.option "comments", "--comments", "If true, output comments in _comments directory (default: false)"
|
42
44
|
end
|
43
45
|
|
44
46
|
# By default this migrator will include posts for all your MovableType blogs.
|
@@ -67,7 +69,7 @@ module JekyllImport
|
|
67
69
|
def self.process(options)
|
68
70
|
options = default_options.merge(options)
|
69
71
|
|
70
|
-
comments = options.fetch(
|
72
|
+
comments = options.fetch("comments")
|
71
73
|
posts_name_by_id = {} if comments
|
72
74
|
|
73
75
|
db = database_from_opts(options)
|
@@ -77,20 +79,20 @@ module JekyllImport
|
|
77
79
|
FileUtils.mkdir_p "_posts"
|
78
80
|
|
79
81
|
posts = db[:mt_entry]
|
80
|
-
posts = posts.filter(:entry_blog_id => options[
|
82
|
+
posts = posts.filter(:entry_blog_id => options["blog_id"]) if options["blog_id"]
|
81
83
|
posts.each do |post|
|
82
84
|
categories = post_categories.filter(
|
83
85
|
:mt_placement__placement_entry_id => post[:entry_id]
|
84
|
-
).map {|ea| encode(ea[:category_basename], options) }
|
86
|
+
).map { |ea| encode(ea[:category_basename], options) }
|
85
87
|
|
86
88
|
file_name = post_file_name(post, options)
|
87
89
|
|
88
90
|
data = post_metadata(post, options)
|
89
|
-
data[
|
90
|
-
yaml_front_matter = data.delete_if { |_,v| v.nil? || v ==
|
91
|
+
data["categories"] = categories if !categories.empty? && options["categories"]
|
92
|
+
yaml_front_matter = data.delete_if { |_, v| v.nil? || v == "" }.to_yaml
|
91
93
|
|
92
94
|
# save post path for comment processing
|
93
|
-
posts_name_by_id[data[
|
95
|
+
posts_name_by_id[data["post_id"]] = file_name if comments
|
94
96
|
|
95
97
|
content = post_content(post, options)
|
96
98
|
|
@@ -107,38 +109,36 @@ module JekyllImport
|
|
107
109
|
|
108
110
|
comments = db[:mt_comment]
|
109
111
|
comments.each do |comment|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
end
|
112
|
+
next unless posts_name_by_id.key?(comment[:comment_entry_id]) # if the entry exists
|
113
|
+
dir_name, base_name = comment_file_dir_and_base_name(posts_name_by_id, comment, options)
|
114
|
+
FileUtils.mkdir_p "_comments/#{dir_name}"
|
115
|
+
|
116
|
+
data = comment_metadata(comment, options)
|
117
|
+
content = comment_content(comment, options)
|
118
|
+
yaml_front_matter = data.delete_if { |_, v| v.nil? || v == "" }.to_yaml
|
119
|
+
|
120
|
+
File.open("_comments/#{dir_name}/#{base_name}", "w") do |f|
|
121
|
+
f.puts yaml_front_matter
|
122
|
+
f.puts "---"
|
123
|
+
f.puts encode(content, options)
|
123
124
|
end
|
124
125
|
end
|
125
126
|
end
|
126
|
-
|
127
127
|
end
|
128
128
|
|
129
129
|
# Extracts metadata for YAML front matter from post
|
130
130
|
def self.post_metadata(post, options = default_options)
|
131
131
|
metadata = {
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
132
|
+
"layout" => "post",
|
133
|
+
"title" => encode(post[:entry_title], options),
|
134
|
+
"date" => post_date(post).strftime("%Y-%m-%d %H:%M:%S %z"),
|
135
|
+
"excerpt" => encode(post[:entry_excerpt].to_s, options),
|
136
|
+
"mt_id" => post[:entry_id],
|
137
|
+
"blog_id" => post[:entry_blog_id],
|
138
|
+
"post_id" => post[:entry_id], # for link with comments
|
139
|
+
"basename" => post[:entry_basename],
|
140
140
|
}
|
141
|
-
metadata[
|
141
|
+
metadata["published"] = false if post[:entry_status] != STATUS_PUBLISHED
|
142
142
|
metadata
|
143
143
|
end
|
144
144
|
|
@@ -152,7 +152,7 @@ module JekyllImport
|
|
152
152
|
post[:entry_text_more].nil? || post[:entry_text_more].strip.empty?
|
153
153
|
end
|
154
154
|
|
155
|
-
def self.post_content(post,
|
155
|
+
def self.post_content(post, _options = default_options)
|
156
156
|
if extra_entry_text_empty?(post)
|
157
157
|
post[:entry_text]
|
158
158
|
else
|
@@ -160,27 +160,27 @@ module JekyllImport
|
|
160
160
|
end
|
161
161
|
end
|
162
162
|
|
163
|
-
def self.post_file_name(post,
|
163
|
+
def self.post_file_name(post, _options = default_options)
|
164
164
|
date = post_date(post)
|
165
165
|
slug = post[:entry_basename]
|
166
166
|
file_ext = suffix(post[:entry_convert_breaks])
|
167
167
|
|
168
|
-
"#{date.strftime(
|
168
|
+
"#{date.strftime("%Y-%m-%d")}-#{slug}.#{file_ext}"
|
169
169
|
end
|
170
170
|
|
171
171
|
# Extracts metadata for YAML front matter from comment
|
172
172
|
def self.comment_metadata(comment, options = default_options)
|
173
173
|
metadata = {
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
174
|
+
"layout" => "comment",
|
175
|
+
"comment_id" => comment[:comment_id],
|
176
|
+
"post_id" => comment[:comment_entry_id],
|
177
|
+
"author" => encode(comment[:comment_author], options),
|
178
|
+
"email" => comment[:comment_email],
|
179
|
+
"commenter_id" => comment[:comment_commenter_id],
|
180
|
+
"date" => comment_date(comment).strftime("%Y-%m-%d %H:%M:%S %z"),
|
181
|
+
"visible" => comment[:comment_visible] == 1,
|
182
|
+
"ip" => comment[:comment_ip],
|
183
|
+
"url" => comment[:comment_url],
|
184
184
|
}
|
185
185
|
metadata
|
186
186
|
end
|
@@ -190,12 +190,12 @@ module JekyllImport
|
|
190
190
|
comment[:comment_modified_on] || comment[:comment_created_on]
|
191
191
|
end
|
192
192
|
|
193
|
-
def self.comment_content(comment,
|
193
|
+
def self.comment_content(comment, _options = default_options)
|
194
194
|
comment[:comment_text]
|
195
195
|
end
|
196
196
|
|
197
|
-
def self.comment_file_dir_and_base_name(posts_name_by_id, comment,
|
198
|
-
post_basename = posts_name_by_id[comment[:comment_entry_id]].sub(
|
197
|
+
def self.comment_file_dir_and_base_name(posts_name_by_id, comment, _options = default_options)
|
198
|
+
post_basename = posts_name_by_id[comment[:comment_entry_id]].sub(%r!\.\w+$!, "")
|
199
199
|
comment_id = comment[:comment_id]
|
200
200
|
|
201
201
|
[post_basename, "#{comment_id}.markdown"]
|
@@ -203,7 +203,7 @@ module JekyllImport
|
|
203
203
|
|
204
204
|
def self.encode(str, options = default_options)
|
205
205
|
if str.respond_to?(:encoding)
|
206
|
-
str.encode(options[
|
206
|
+
str.encode(options["dest_encoding"], options["src_encoding"])
|
207
207
|
else
|
208
208
|
str
|
209
209
|
end
|
@@ -230,26 +230,27 @@ module JekyllImport
|
|
230
230
|
end
|
231
231
|
|
232
232
|
def self.database_from_opts(options)
|
233
|
-
engine
|
234
|
-
dbname
|
233
|
+
engine = options.fetch("engine", "mysql")
|
234
|
+
dbname = options.fetch("dbname")
|
235
|
+
sequel_engine = engine == "mysql" ? "mysql2" : engine
|
235
236
|
|
236
237
|
case engine
|
237
238
|
when "sqlite"
|
238
239
|
Sequel.sqlite(dbname)
|
239
240
|
when "mysql", "postgres"
|
240
241
|
db_connect_opts = {
|
241
|
-
:host
|
242
|
-
:user
|
243
|
-
:password => options.fetch(
|
242
|
+
:host => options.fetch("host", "localhost"),
|
243
|
+
:user => options.fetch("user"),
|
244
|
+
:password => options.fetch("password", ""),
|
244
245
|
}
|
245
|
-
db_connect_opts = options[
|
246
|
+
db_connect_opts = options["port"] if options["port"]
|
246
247
|
Sequel.public_send(
|
247
|
-
|
248
|
+
sequel_engine,
|
248
249
|
dbname,
|
249
250
|
db_connect_opts
|
250
251
|
)
|
251
252
|
else
|
252
|
-
abort("Unsupported engine: '#{engine}'. Must be one of #{SUPPORTED_ENGINES.join(
|
253
|
+
abort("Unsupported engine: '#{engine}'. Must be one of #{SUPPORTED_ENGINES.join(", ")}")
|
253
254
|
end
|
254
255
|
end
|
255
256
|
end
|