jekyll-import 0.12.0 → 0.13.0
Sign up to get free protection for your applications and to get access to all the features.
- 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,7 +2,7 @@ module JekyllImport
|
|
2
2
|
module Importers
|
3
3
|
class Typo < Importer
|
4
4
|
# This SQL *should* work for both MySQL and PostgreSQL.
|
5
|
-
SQL = <<-EOS
|
5
|
+
SQL = <<-EOS.freeze
|
6
6
|
SELECT c.id id,
|
7
7
|
c.title title,
|
8
8
|
c.permalink slug,
|
@@ -18,42 +18,44 @@ module JekyllImport
|
|
18
18
|
EOS
|
19
19
|
|
20
20
|
def self.require_deps
|
21
|
-
JekyllImport.require_with_fallback(%w
|
21
|
+
JekyllImport.require_with_fallback(%w(
|
22
22
|
rubygems
|
23
23
|
sequel
|
24
|
+
mysql2
|
25
|
+
pg
|
24
26
|
fileutils
|
25
27
|
safe_yaml
|
26
|
-
|
28
|
+
))
|
27
29
|
end
|
28
30
|
|
29
31
|
def self.specify_options(c)
|
30
|
-
c.option
|
31
|
-
c.option
|
32
|
-
c.option
|
33
|
-
c.option
|
34
|
-
c.option
|
32
|
+
c.option "server", "--server TYPE", 'Server type ("mysql" or "postgres")'
|
33
|
+
c.option "dbname", "--dbname DB", "Database name"
|
34
|
+
c.option "user", "--user USER", "Database user name"
|
35
|
+
c.option "password", "--password PW", "Database user's password (default: '')"
|
36
|
+
c.option "host", "--host HOST", "Database host name"
|
35
37
|
end
|
36
38
|
|
37
39
|
def self.process(options)
|
38
|
-
server = options.fetch(
|
39
|
-
dbname = options.fetch(
|
40
|
-
user = options.fetch(
|
41
|
-
pass = options.fetch(
|
42
|
-
host = options.fetch(
|
40
|
+
server = options.fetch("server")
|
41
|
+
dbname = options.fetch("dbname")
|
42
|
+
user = options.fetch("user")
|
43
|
+
pass = options.fetch("password", "")
|
44
|
+
host = options.fetch("host", "localhost")
|
43
45
|
|
44
|
-
FileUtils.mkdir_p
|
46
|
+
FileUtils.mkdir_p "_posts"
|
45
47
|
case server.intern
|
46
48
|
when :postgres
|
47
|
-
db = Sequel.postgres(dbname, :user => user, :password => pass, :host => host, :encoding =>
|
49
|
+
db = Sequel.postgres(dbname, :user => user, :password => pass, :host => host, :encoding => "utf8")
|
48
50
|
when :mysql
|
49
|
-
db = Sequel.
|
51
|
+
db = Sequel.mysql2(dbname, :user => user, :password => pass, :host => host, :encoding => "utf8")
|
50
52
|
else
|
51
53
|
raise "Unknown database server '#{server}'"
|
52
54
|
end
|
53
55
|
db[SQL].each do |post|
|
54
|
-
next unless post[:state] =~
|
56
|
+
next unless post[:state] =~ %r!published!i
|
55
57
|
|
56
|
-
if post[:slug]
|
58
|
+
if post[:slug].nil?
|
57
59
|
post[:slug] = "no slug"
|
58
60
|
end
|
59
61
|
|
@@ -62,27 +64,25 @@ module JekyllImport
|
|
62
64
|
post[:body] << post[:extended]
|
63
65
|
end
|
64
66
|
|
65
|
-
name = [
|
66
|
-
|
67
|
-
|
68
|
-
post[:slug].strip ].join(
|
67
|
+
name = [ format("%.04d", post[:date].year),
|
68
|
+
format("%.02d", post[:date].month),
|
69
|
+
format("%.02d", post[:date].day),
|
70
|
+
post[:slug].strip, ].join("-")
|
69
71
|
|
70
72
|
# Can have more than one text filter in this field, but we just want
|
71
73
|
# the first one for this.
|
72
|
-
name +=
|
74
|
+
name += "." + post[:filter].split(" ")[0]
|
73
75
|
|
74
|
-
File.open("_posts/#{name}",
|
75
|
-
f.puts({
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
f.puts '---'
|
76
|
+
File.open("_posts/#{name}", "w") do |f|
|
77
|
+
f.puts({ "layout" => "post",
|
78
|
+
"title" => (post[:title] && post[:title].to_s.force_encoding("UTF-8")),
|
79
|
+
"tags" => (post[:keywords] && post[:keywords].to_s.force_encoding("UTF-8")),
|
80
|
+
"typo_id" => post[:id], }.delete_if { |_k, v| v.nil? || v == "" }.to_yaml)
|
81
|
+
f.puts "---"
|
81
82
|
f.puts post[:body].delete("\r")
|
82
83
|
end
|
83
84
|
end
|
84
85
|
end
|
85
|
-
|
86
86
|
end
|
87
87
|
end
|
88
88
|
end
|
@@ -1,32 +1,32 @@
|
|
1
1
|
module JekyllImport
|
2
2
|
module Importers
|
3
3
|
class WordPress < Importer
|
4
|
-
|
5
4
|
def self.require_deps
|
6
|
-
JekyllImport.require_with_fallback(%w
|
5
|
+
JekyllImport.require_with_fallback(%w(
|
7
6
|
rubygems
|
8
7
|
sequel
|
9
8
|
fileutils
|
10
9
|
safe_yaml
|
11
10
|
unidecode
|
12
|
-
|
11
|
+
))
|
13
12
|
end
|
14
13
|
|
15
14
|
def self.specify_options(c)
|
16
|
-
c.option
|
17
|
-
c.option
|
18
|
-
c.option
|
19
|
-
c.option
|
20
|
-
c.option
|
21
|
-
c.option
|
22
|
-
c.option
|
23
|
-
c.option
|
24
|
-
c.option
|
25
|
-
c.option
|
26
|
-
c.option
|
27
|
-
c.option
|
28
|
-
c.option
|
29
|
-
c.option
|
15
|
+
c.option "dbname", "--dbname DB", "Database name (default: '')"
|
16
|
+
c.option "socket", "--socket SOCKET", "Database socket (default: '')"
|
17
|
+
c.option "user", "--user USER", "Database user name (default: '')"
|
18
|
+
c.option "password", "--password PW", "Database user's password (default: '')"
|
19
|
+
c.option "host", "--host HOST", "Database host name (default: 'localhost')"
|
20
|
+
c.option "port", "--port PORT", "Database port number (default: '')"
|
21
|
+
c.option "table_prefix", "--table_prefix PREFIX", "Table prefix name (default: 'wp_')"
|
22
|
+
c.option "site_prefix", "--site_prefix PREFIX", "Site prefix name (default: '')"
|
23
|
+
c.option "clean_entities", "--clean_entities", "Whether to clean entities (default: true)"
|
24
|
+
c.option "comments", "--comments", "Whether to import comments (default: true)"
|
25
|
+
c.option "categories", "--categories", "Whether to import categories (default: true)"
|
26
|
+
c.option "tags", "--tags", "Whether to import tags (default: true)"
|
27
|
+
c.option "more_excerpt", "--more_excerpt", "Whether to use more excerpt (default: true)"
|
28
|
+
c.option "more_anchor", "--more_anchor", "Whether to use more anchor (default: true)"
|
29
|
+
c.option "status", "--status STATUS,STATUS2", Array, "Array of allowed statuses (default: ['publish'], other options: 'draft', 'private', 'revision')"
|
30
30
|
end
|
31
31
|
|
32
32
|
# Main migrator function. Call this to perform the migration.
|
@@ -35,6 +35,7 @@ module JekyllImport
|
|
35
35
|
# user:: The database user name
|
36
36
|
# pass:: The database user's password
|
37
37
|
# host:: The address of the MySQL database host. Default: 'localhost'
|
38
|
+
# port:: The port number of the MySQL database. Default: '3306'
|
38
39
|
# socket:: The database socket's path
|
39
40
|
# options:: A hash table of configuration options.
|
40
41
|
#
|
@@ -74,28 +75,29 @@ module JekyllImport
|
|
74
75
|
#
|
75
76
|
def self.process(opts)
|
76
77
|
options = {
|
77
|
-
:user => opts.fetch(
|
78
|
-
:pass => opts.fetch(
|
79
|
-
:host => opts.fetch(
|
80
|
-
:
|
81
|
-
:
|
82
|
-
:
|
83
|
-
:
|
84
|
-
:
|
85
|
-
:
|
86
|
-
:
|
87
|
-
:
|
88
|
-
:
|
89
|
-
:
|
90
|
-
:
|
91
|
-
:
|
78
|
+
:user => opts.fetch("user", ""),
|
79
|
+
:pass => opts.fetch("password", ""),
|
80
|
+
:host => opts.fetch("host", "localhost"),
|
81
|
+
:port => opts.fetch("port", "3306"),
|
82
|
+
:socket => opts.fetch("socket", nil),
|
83
|
+
:dbname => opts.fetch("dbname", ""),
|
84
|
+
:table_prefix => opts.fetch("table_prefix", "wp_"),
|
85
|
+
:site_prefix => opts.fetch("site_prefix", nil),
|
86
|
+
:clean_entities => opts.fetch("clean_entities", true),
|
87
|
+
:comments => opts.fetch("comments", true),
|
88
|
+
:categories => opts.fetch("categories", true),
|
89
|
+
:tags => opts.fetch("tags", true),
|
90
|
+
:more_excerpt => opts.fetch("more_excerpt", true),
|
91
|
+
:more_anchor => opts.fetch("more_anchor", true),
|
92
|
+
:extension => opts.fetch("extension", "html"),
|
93
|
+
:status => opts.fetch("status", ["publish"]).map(&:to_sym) # :draft, :private, :revision
|
92
94
|
}
|
93
95
|
|
94
96
|
if options[:clean_entities]
|
95
97
|
begin
|
96
|
-
require
|
98
|
+
require "htmlentities"
|
97
99
|
rescue LoadError
|
98
|
-
STDERR.puts "Could not require 'htmlentities', so the "
|
100
|
+
STDERR.puts "Could not require 'htmlentities', so the " \
|
99
101
|
":clean_entities option is now disabled."
|
100
102
|
options[:clean_entities] = false
|
101
103
|
end
|
@@ -104,8 +106,13 @@ module JekyllImport
|
|
104
106
|
FileUtils.mkdir_p("_posts")
|
105
107
|
FileUtils.mkdir_p("_drafts") if options[:status].include? :draft
|
106
108
|
|
107
|
-
db = Sequel.mysql2(options[:dbname],
|
108
|
-
|
109
|
+
db = Sequel.mysql2(options[:dbname],
|
110
|
+
:user => options[:user],
|
111
|
+
:password => options[:pass],
|
112
|
+
:socket => options[:socket],
|
113
|
+
:host => options[:host],
|
114
|
+
:port => options[:port],
|
115
|
+
:encoding => "utf8")
|
109
116
|
|
110
117
|
px = options[:table_prefix]
|
111
118
|
sx = options[:site_prefix]
|
@@ -122,12 +129,12 @@ module JekyllImport
|
|
122
129
|
WHERE posts.post_type = 'page'"
|
123
130
|
|
124
131
|
db[page_name_query].each do |page|
|
125
|
-
if !page[:slug]
|
132
|
+
if !page[:slug] || page[:slug].empty?
|
126
133
|
page[:slug] = sluggify(page[:title])
|
127
134
|
end
|
128
135
|
page_name_list[ page[:id] ] = {
|
129
136
|
:slug => page[:slug],
|
130
|
-
:parent => page[:parent]
|
137
|
+
:parent => page[:parent],
|
131
138
|
}
|
132
139
|
end
|
133
140
|
|
@@ -152,13 +159,13 @@ module JekyllImport
|
|
152
159
|
LEFT JOIN #{px}users AS `users`
|
153
160
|
ON posts.post_author = users.ID"
|
154
161
|
|
155
|
-
if options[:status]
|
162
|
+
if options[:status] && !options[:status].empty?
|
156
163
|
status = options[:status][0]
|
157
164
|
posts_query << "
|
158
|
-
WHERE posts.post_status = '#{status
|
165
|
+
WHERE posts.post_status = '#{status}'"
|
159
166
|
options[:status][1..-1].each do |status|
|
160
167
|
posts_query << " OR
|
161
|
-
posts.post_status = '#{status
|
168
|
+
posts.post_status = '#{status}'"
|
162
169
|
end
|
163
170
|
end
|
164
171
|
|
@@ -167,7 +174,6 @@ module JekyllImport
|
|
167
174
|
end
|
168
175
|
end
|
169
176
|
|
170
|
-
|
171
177
|
def self.process_post(post, db, options, page_name_list)
|
172
178
|
px = options[:table_prefix]
|
173
179
|
sx = options[:site_prefix]
|
@@ -179,13 +185,12 @@ module JekyllImport
|
|
179
185
|
end
|
180
186
|
|
181
187
|
slug = post[:slug]
|
182
|
-
if !slug
|
188
|
+
if !slug || slug.empty?
|
183
189
|
slug = sluggify(title)
|
184
190
|
end
|
185
191
|
|
186
192
|
date = post[:date] || Time.now
|
187
|
-
name = "%02d-%02d-%02d-%s.%s"
|
188
|
-
slug, extension]
|
193
|
+
name = format("%02d-%02d-%02d-%s.%s", date.year, date.month, date.day, slug, extension)
|
189
194
|
content = post[:content].to_s
|
190
195
|
if options[:clean_entities]
|
191
196
|
content = clean_entities(content)
|
@@ -193,17 +198,17 @@ module JekyllImport
|
|
193
198
|
|
194
199
|
excerpt = post[:excerpt].to_s
|
195
200
|
|
196
|
-
more_index = content.index(/<!-- *more
|
201
|
+
more_index = content.index(%r/<!-- *more* -->/)
|
197
202
|
more_anchor = nil
|
198
203
|
if more_index
|
199
|
-
if options[:more_excerpt]
|
200
|
-
(post[:excerpt].nil?
|
204
|
+
if options[:more_excerpt] &&
|
205
|
+
(post[:excerpt].nil? || post[:excerpt].empty?)
|
201
206
|
excerpt = content[0...more_index]
|
202
207
|
end
|
203
208
|
if options[:more_anchor]
|
204
|
-
|
205
|
-
content.sub!(/<!-- *more *-->/,
|
206
|
-
"<a id=\"more\"></a>"
|
209
|
+
more_anchor = "more"
|
210
|
+
content.sub!(%r/<!-- *more *-->/,
|
211
|
+
"<a id=\"more\"></a>" \
|
207
212
|
"<a id=\"more-#{post[:id]}\"></a>")
|
208
213
|
end
|
209
214
|
end
|
@@ -211,7 +216,7 @@ module JekyllImport
|
|
211
216
|
categories = []
|
212
217
|
tags = []
|
213
218
|
|
214
|
-
if options[:categories]
|
219
|
+
if options[:categories] || options[:tags]
|
215
220
|
|
216
221
|
cquery =
|
217
222
|
"SELECT
|
@@ -227,13 +232,13 @@ module JekyllImport
|
|
227
232
|
terms.term_id = ttax.term_id"
|
228
233
|
|
229
234
|
db[cquery].each do |term|
|
230
|
-
if options[:categories]
|
235
|
+
if options[:categories] && term[:type] == "category"
|
231
236
|
if options[:clean_entities]
|
232
237
|
categories << clean_entities(term[:name])
|
233
238
|
else
|
234
239
|
categories << term[:name]
|
235
240
|
end
|
236
|
-
elsif options[:tags]
|
241
|
+
elsif options[:tags] && term[:type] == "post_tag"
|
237
242
|
if options[:clean_entities]
|
238
243
|
tags << clean_entities(term[:name])
|
239
244
|
else
|
@@ -245,7 +250,7 @@ module JekyllImport
|
|
245
250
|
|
246
251
|
comments = []
|
247
252
|
|
248
|
-
if options[:comments]
|
253
|
+
if options[:comments] && post[:comment_count].to_i > 0
|
249
254
|
cquery =
|
250
255
|
"SELECT
|
251
256
|
comment_ID AS `id`,
|
@@ -260,9 +265,7 @@ module JekyllImport
|
|
260
265
|
comment_post_ID = '#{post[:id]}' AND
|
261
266
|
comment_approved != 'spam'"
|
262
267
|
|
263
|
-
|
264
268
|
db[cquery].each do |comment|
|
265
|
-
|
266
269
|
comcontent = comment[:content].to_s
|
267
270
|
if comcontent.respond_to?(:force_encoding)
|
268
271
|
comcontent.force_encoding("UTF-8")
|
@@ -276,50 +279,50 @@ module JekyllImport
|
|
276
279
|
end
|
277
280
|
|
278
281
|
comments << {
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
282
|
+
"id" => comment[:id].to_i,
|
283
|
+
"author" => comauthor,
|
284
|
+
"author_email" => comment[:author_email].to_s,
|
285
|
+
"author_url" => comment[:author_url].to_s,
|
286
|
+
"date" => comment[:date].to_s,
|
287
|
+
"date_gmt" => comment[:date_gmt].to_s,
|
288
|
+
"content" => comcontent,
|
286
289
|
}
|
287
290
|
end
|
288
291
|
|
289
|
-
comments.sort!{ |a,b| a[
|
292
|
+
comments.sort! { |a, b| a["id"] <=> b["id"] }
|
290
293
|
end
|
291
294
|
|
292
295
|
# Get the relevant fields as a hash, delete empty fields and
|
293
296
|
# convert to YAML for the header.
|
294
297
|
data = {
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
298
|
+
"layout" => post[:type].to_s,
|
299
|
+
"status" => post[:status].to_s,
|
300
|
+
"published" => post[:status].to_s == "draft" ? nil : (post[:status].to_s == "publish"),
|
301
|
+
"title" => title.to_s,
|
302
|
+
"author" => {
|
303
|
+
"display_name" => post[:author].to_s,
|
304
|
+
"login" => post[:author_login].to_s,
|
305
|
+
"email" => post[:author_email].to_s,
|
306
|
+
"url" => post[:author_url].to_s,
|
304
307
|
},
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
}.delete_if { |
|
318
|
-
|
319
|
-
if post[:type] ==
|
308
|
+
"author_login" => post[:author_login].to_s,
|
309
|
+
"author_email" => post[:author_email].to_s,
|
310
|
+
"author_url" => post[:author_url].to_s,
|
311
|
+
"excerpt" => excerpt,
|
312
|
+
"more_anchor" => more_anchor,
|
313
|
+
"wordpress_id" => post[:id],
|
314
|
+
"wordpress_url" => post[:guid].to_s,
|
315
|
+
"date" => date.to_s,
|
316
|
+
"date_gmt" => post[:date_gmt].to_s,
|
317
|
+
"categories" => options[:categories] ? categories : nil,
|
318
|
+
"tags" => options[:tags] ? tags : nil,
|
319
|
+
"comments" => options[:comments] ? comments : nil,
|
320
|
+
}.delete_if { |_k, v| v.nil? || v == "" }.to_yaml
|
321
|
+
|
322
|
+
if post[:type] == "page"
|
320
323
|
filename = page_path(post[:id], page_name_list) + "index.#{extension}"
|
321
324
|
FileUtils.mkdir_p(File.dirname(filename))
|
322
|
-
elsif post[:status] ==
|
325
|
+
elsif post[:status] == "draft"
|
323
326
|
filename = "_drafts/#{slug}.md"
|
324
327
|
else
|
325
328
|
filename = "_posts/#{name}"
|
@@ -333,8 +336,7 @@ module JekyllImport
|
|
333
336
|
end
|
334
337
|
end
|
335
338
|
|
336
|
-
|
337
|
-
def self.clean_entities( text )
|
339
|
+
def self.clean_entities(text)
|
338
340
|
if text.respond_to?(:force_encoding)
|
339
341
|
text.force_encoding("UTF-8")
|
340
342
|
end
|
@@ -346,27 +348,25 @@ module JekyllImport
|
|
346
348
|
text.gsub!(">", ">")
|
347
349
|
text.gsub!(""", '"')
|
348
350
|
text.gsub!("'", "'")
|
349
|
-
text.gsub!("
|
351
|
+
text.gsub!("/", "/")
|
350
352
|
text
|
351
353
|
end
|
352
354
|
|
353
|
-
|
354
|
-
|
355
|
-
title = title.to_ascii.downcase.gsub(/[^0-9A-Za-z]+/, " ").strip.gsub(" ", "-")
|
355
|
+
def self.sluggify(title)
|
356
|
+
title.to_ascii.downcase.gsub(%r![^0-9A-Za-z]+!, " ").strip.tr(" ", "-")
|
356
357
|
end
|
357
358
|
|
358
|
-
def self.page_path(
|
359
|
+
def self.page_path(page_id, page_name_list)
|
359
360
|
if page_name_list.key?(page_id)
|
360
361
|
[
|
361
|
-
page_path(page_name_list[page_id][:parent],page_name_list),
|
362
|
+
page_path(page_name_list[page_id][:parent], page_name_list),
|
362
363
|
page_name_list[page_id][:slug],
|
363
|
-
|
364
|
+
"/",
|
364
365
|
].join("")
|
365
366
|
else
|
366
367
|
""
|
367
368
|
end
|
368
369
|
end
|
369
|
-
|
370
370
|
end
|
371
371
|
end
|
372
372
|
end
|