jekyll-import 0.8.0 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.markdown +1 -1
- data/lib/jekyll-import/importers/blogger.rb +17 -15
- data/lib/jekyll-import/importers/joomla.rb +18 -4
- data/lib/jekyll-import/importers/joomla3.rb +91 -0
- data/lib/jekyll-import/importers/mt.rb +21 -1
- data/lib/jekyll-import/importers/tumblr.rb +5 -3
- data/lib/jekyll-import/importers/wordpressdotcom.rb +4 -2
- data/lib/jekyll-import/version.rb +1 -1
- data/lib/jekyll/commands/import.rb +1 -0
- metadata +18 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 07d3bbdc383ff8bcf6b7b686332687345dc8a71b
|
4
|
+
data.tar.gz: 73fa392dc3e4957d0aae9dce535a0abb3655c73f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 32ddb7124f545ddc9031190529a40348051b713c2343f509ce26bc7970310ed456ed59e0dd7f4a7baaafde3141cd3248f42b85f47d3d26b237b090d452ade2d7
|
7
|
+
data.tar.gz: 6331a88ff5fe73131e7d4f0331e0767ff4871b190135260f42af846a2ea0b2f2c989ae678c0992400ac2defe3818a2d34b16fdf2bb3e26fc52a36a7b4af767ef
|
data/README.markdown
CHANGED
@@ -8,7 +8,7 @@ The new __Jekyll__ command for importing from various blogs to Jekyll format.
|
|
8
8
|
|
9
9
|
## How `jekyll-import` works:
|
10
10
|
|
11
|
-
### Jekyll v2.x
|
11
|
+
### Jekyll v2.x and higher
|
12
12
|
|
13
13
|
1. Install the _rubygem_ with `gem install jekyll-import`.
|
14
14
|
2. Run `jekyll import IMPORTER [options]`
|
@@ -24,6 +24,7 @@ module JekyllImport
|
|
24
24
|
time
|
25
25
|
fileutils
|
26
26
|
safe_yaml
|
27
|
+
open-uri
|
27
28
|
])
|
28
29
|
end
|
29
30
|
|
@@ -100,11 +101,11 @@ module JekyllImport
|
|
100
101
|
module BloggerAtomStreamListenerMethods
|
101
102
|
attr_accessor :leave_blogger_info
|
102
103
|
attr_reader :original_url_base
|
103
|
-
|
104
|
+
|
104
105
|
def tag_start(tag, attrs)
|
105
106
|
@tag_bread = [] unless @tag_bread
|
106
107
|
@tag_bread.push(tag)
|
107
|
-
|
108
|
+
|
108
109
|
case tag
|
109
110
|
when 'entry'
|
110
111
|
raise 'nest entry element' if @in_entry_elem
|
@@ -144,7 +145,7 @@ module JekyllImport
|
|
144
145
|
end
|
145
146
|
end
|
146
147
|
end
|
147
|
-
|
148
|
+
|
148
149
|
def text(text)
|
149
150
|
if @in_entry_elem
|
150
151
|
case @tag_bread.last
|
@@ -168,13 +169,13 @@ module JekyllImport
|
|
168
169
|
end
|
169
170
|
end
|
170
171
|
end
|
171
|
-
end
|
172
|
-
|
172
|
+
end
|
173
|
+
|
173
174
|
def tag_end(tag)
|
174
175
|
case tag
|
175
176
|
when 'entry'
|
176
177
|
raise 'nest entry element' unless @in_entry_elem
|
177
|
-
|
178
|
+
|
178
179
|
if @in_entry_elem[:meta][:kind] == 'post'
|
179
180
|
post_data = get_post_data_from_in_entry_elem_info
|
180
181
|
|
@@ -183,20 +184,21 @@ module JekyllImport
|
|
183
184
|
target_dir = '_drafts' if @in_entry_elem[:meta][:draft]
|
184
185
|
|
185
186
|
FileUtils.mkdir_p(target_dir)
|
186
|
-
|
187
|
-
|
187
|
+
|
188
|
+
file_name = URI::decode("#{post_data[:filename]}.html")
|
189
|
+
File.open(File.join(target_dir, file_name), 'w') do |f|
|
188
190
|
f.flock(File::LOCK_EX)
|
189
|
-
|
191
|
+
|
190
192
|
f << post_data[:header].to_yaml
|
191
193
|
f << "---\n\n"
|
192
194
|
f << post_data[:body]
|
193
195
|
end
|
194
196
|
end
|
195
197
|
end
|
196
|
-
|
198
|
+
|
197
199
|
@in_entry_elem = nil
|
198
200
|
end
|
199
|
-
|
201
|
+
|
200
202
|
@tag_bread.pop
|
201
203
|
end
|
202
204
|
|
@@ -223,10 +225,10 @@ module JekyllImport
|
|
223
225
|
[timestamp,
|
224
226
|
CGI.escape(name.downcase).tr('+','-')]
|
225
227
|
end
|
226
|
-
else
|
228
|
+
else
|
227
229
|
raise 'Original URL is missing'
|
228
230
|
end
|
229
|
-
|
231
|
+
|
230
232
|
header = {
|
231
233
|
'layout' => 'post',
|
232
234
|
'title' => @in_entry_elem[:meta][:title],
|
@@ -238,7 +240,7 @@ module JekyllImport
|
|
238
240
|
header['thumbnail'] = @in_entry_elem[:meta][:thumbnail] if @in_entry_elem[:meta][:thumbnail]
|
239
241
|
header['blogger_id'] = @in_entry_elem[:meta][:id] if @leave_blogger_info
|
240
242
|
header['blogger_orig_url'] = @in_entry_elem[:meta][:original_url] if @leave_blogger_info && @in_entry_elem[:meta][:original_url]
|
241
|
-
|
243
|
+
|
242
244
|
body = @in_entry_elem[:body]
|
243
245
|
|
244
246
|
# body escaping associated with liquid
|
@@ -248,7 +250,7 @@ module JekyllImport
|
|
248
250
|
if body =~ /{%/
|
249
251
|
body.gsub!(/{%/, '{{ "{%" }}')
|
250
252
|
end
|
251
|
-
|
253
|
+
|
252
254
|
{ :filename => filename, :header => header, :body => body }
|
253
255
|
else
|
254
256
|
nil
|
@@ -42,16 +42,25 @@ module JekyllImport
|
|
42
42
|
# Reads a MySQL database via Sequel and creates a post file for each
|
43
43
|
# post in wp_posts that has post_status = 'publish'. This restriction is
|
44
44
|
# made because 'draft' posts are not guaranteed to have valid dates.
|
45
|
-
query = "SELECT `title`, `alias`, CONCAT(`introtext`,`fulltext`) as content, `created`, `id` FROM #{table_prefix}content WHERE state = '0' OR state = '1' AND sectionid = '#{section}'"
|
45
|
+
query = "SELECT `title`, `alias`, CONCAT(`introtext`,`fulltext`) as content, `created`, `id` FROM #{table_prefix}content WHERE (state = '0' OR state = '1') AND sectionid = '#{section}'"
|
46
46
|
|
47
47
|
db[query].each do |post|
|
48
48
|
# Get required fields and construct Jekyll compatible name.
|
49
49
|
title = post[:title]
|
50
|
-
slug = post[:alias]
|
51
50
|
date = post[:created]
|
52
51
|
content = post[:content]
|
53
|
-
|
54
|
-
|
52
|
+
id = post[:id]
|
53
|
+
|
54
|
+
# Construct a slug from the title if alias field empty.
|
55
|
+
# Remove illegal filename characters.
|
56
|
+
if !post[:alias] or post[:alias].empty?
|
57
|
+
slug = sluggify(post[:title])
|
58
|
+
else
|
59
|
+
slug = sluggify(post[:alias])
|
60
|
+
end
|
61
|
+
|
62
|
+
name = "%02d-%02d-%02d-%03d-%s.markdown" % [date.year, date.month, date.day,
|
63
|
+
id,slug]
|
55
64
|
|
56
65
|
# Get the relevant fields as a hash, delete empty fields and convert
|
57
66
|
# to YAML for the header.
|
@@ -71,6 +80,11 @@ module JekyllImport
|
|
71
80
|
end
|
72
81
|
end
|
73
82
|
end
|
83
|
+
|
84
|
+
# Borrowed from the Wordpress importer
|
85
|
+
def self.sluggify( title )
|
86
|
+
title = title.downcase.gsub(/[^0-9A-Za-z]+/, " ").strip.gsub(" ", "-")
|
87
|
+
end
|
74
88
|
end
|
75
89
|
end
|
76
90
|
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module JekyllImport
|
2
|
+
module Importers
|
3
|
+
class Joomla3 < Importer
|
4
|
+
def self.validate(options)
|
5
|
+
%w[dbname user prefix].each do |option|
|
6
|
+
if options[option].nil?
|
7
|
+
abort "Missing mandatory option --#{option}."
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
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 'category', '--category', 'ID of the category'
|
18
|
+
c.option 'prefix', '--prefix', 'Table prefix name'
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.require_deps
|
22
|
+
JekyllImport.require_with_fallback(%w[
|
23
|
+
rubygems
|
24
|
+
sequel
|
25
|
+
fileutils
|
26
|
+
safe_yaml
|
27
|
+
])
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.process(options)
|
31
|
+
dbname = options.fetch('dbname')
|
32
|
+
user = options.fetch('user')
|
33
|
+
pass = options.fetch('password', '')
|
34
|
+
host = options.fetch('host', "localhost")
|
35
|
+
cid = options.fetch('category', 0)
|
36
|
+
table_prefix = options.fetch('prefix', "jos_")
|
37
|
+
|
38
|
+
db = Sequel.mysql(dbname, :user => user, :password => pass, :host => host, :encoding => 'utf8')
|
39
|
+
|
40
|
+
FileUtils.mkdir_p("_posts")
|
41
|
+
|
42
|
+
# Reads a MySQL database via Sequel and creates a post file for each
|
43
|
+
# post in #__content that is published.
|
44
|
+
query = "SELECT `cn`.`title`, `cn`.`alias`, `cn`.`introtext`, CONCAT(`cn`.`introtext`,`cn`.`fulltext`) AS `content`, "
|
45
|
+
query << "`cn`.`created`, `cn`.`id`, `ct`.`title` AS `category`, `u`.`name` AS `author` "
|
46
|
+
query << "FROM `#{table_prefix}content` AS `cn` JOIN `#{table_prefix}categories` AS `ct` ON `cn`.`catid` = `ct`.`id` "
|
47
|
+
query << "JOIN `#{table_prefix}users` AS `u` ON `cn`.`created_by` = `u`.`id` "
|
48
|
+
query << "WHERE (`cn`.`state` = '1' OR `cn`.`state` = '2') " # Only published and archived content items to be imported
|
49
|
+
|
50
|
+
if cid > 0
|
51
|
+
query << " AND `cn`.`catid` = '#{cid}' "
|
52
|
+
else
|
53
|
+
query << " AND `cn`.`catid` != '2' " #Filter out uncategorized content
|
54
|
+
end
|
55
|
+
|
56
|
+
db[query].each do |post|
|
57
|
+
# Get required fields and construct Jekyll compatible name.
|
58
|
+
title = post[:title]
|
59
|
+
slug = post[:alias]
|
60
|
+
date = post[:created]
|
61
|
+
author = post[:author]
|
62
|
+
category = post[:category]
|
63
|
+
content = post[:content]
|
64
|
+
excerpt = post[:introtext]
|
65
|
+
name = "%02d-%02d-%02d-%s.markdown" % [date.year, date.month, date.day,
|
66
|
+
slug]
|
67
|
+
|
68
|
+
# Get the relevant fields as a hash, delete empty fields and convert
|
69
|
+
# to YAML for the header.
|
70
|
+
data = {
|
71
|
+
'layout' => 'post',
|
72
|
+
'title' => title.to_s,
|
73
|
+
'joomla_id' => post[:id],
|
74
|
+
'joomla_url' => slug,
|
75
|
+
'date' => date,
|
76
|
+
'author' => author,
|
77
|
+
'excerpt' => excerpt.strip.to_s,
|
78
|
+
'category' => category
|
79
|
+
}.delete_if { |k,v| v.nil? || v == '' }.to_yaml
|
80
|
+
|
81
|
+
# Write out the data and content to file
|
82
|
+
File.open("_posts/#{name}", "w") do |f|
|
83
|
+
f.puts data
|
84
|
+
f.puts "---"
|
85
|
+
f.puts content
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -26,10 +26,17 @@ module JekyllImport
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def self.specify_options(c)
|
29
|
+
c.option 'engine', "--engine ENGINE", "Database engine, (default: 'mysql', postgres also supported)"
|
29
30
|
c.option 'dbname', '--dbname DB', 'Database name'
|
30
31
|
c.option 'user', '--user USER', 'Database user name'
|
31
32
|
c.option 'password', '--password PW', "Database user's password, (default: '')"
|
32
33
|
c.option 'host', '--host HOST', 'Database host name (default: "localhost")'
|
34
|
+
c.option 'port', '--port PORT', 'Custom database port connect to (optional)'
|
35
|
+
c.option 'blog_id', '--blog_id ID', 'Specify a single Movable Type blog ID to import (default: all blogs)'
|
36
|
+
c.option 'categories', '--categories', "If true, save post's categories in its YAML front matter. (default: true)"
|
37
|
+
c.option 'src_encoding', '--src_encoding ENCODING', "Encoding of strings from database. (default: UTF-8)"
|
38
|
+
c.option 'dest_encoding', '--dest_encoding ENCODING', "Encoding of output strings. (default: UTF-8)"
|
39
|
+
c.option 'comments','--comments', "If true, output comments in _comments directory (default: false)"
|
33
40
|
end
|
34
41
|
|
35
42
|
# By default this migrator will include posts for all your MovableType blogs.
|
@@ -58,6 +65,7 @@ module JekyllImport
|
|
58
65
|
def self.process(options)
|
59
66
|
options = default_options.merge(options)
|
60
67
|
|
68
|
+
engine = options.fetch('engine', 'mysql')
|
61
69
|
dbname = options.fetch('dbname')
|
62
70
|
user = options.fetch('user')
|
63
71
|
pass = options.fetch('password', "")
|
@@ -66,7 +74,19 @@ module JekyllImport
|
|
66
74
|
|
67
75
|
posts_name_by_id = { } if comments
|
68
76
|
|
69
|
-
|
77
|
+
db_opts = { user => user, :password => pass, :host => host }
|
78
|
+
|
79
|
+
# Use the default port by default, but set the port if one is provided.
|
80
|
+
if options['port']
|
81
|
+
db_opts[:port] = options['port']
|
82
|
+
end
|
83
|
+
|
84
|
+
if engine != 'mysql' && engine != 'postgres'
|
85
|
+
abort("unsupported --engine value supplied '#{engine}'. Only 'mysql' and 'postgres' are supported")
|
86
|
+
end
|
87
|
+
|
88
|
+
db = Sequel.public_send(engine, dbname, db_opts)
|
89
|
+
|
70
90
|
post_categories = db[:mt_placement].join(:mt_category, :category_id => :placement_category_id)
|
71
91
|
|
72
92
|
FileUtils.mkdir_p "_posts"
|
@@ -152,9 +152,11 @@ module JekyllImport
|
|
152
152
|
title = "no title" if title.empty?
|
153
153
|
slug = if post["slug"] && post["slug"].strip != ""
|
154
154
|
post["slug"]
|
155
|
-
|
156
|
-
slug = title.downcase.strip.gsub(' ', '-').gsub(/[
|
155
|
+
elsif title && title.downcase.gsub(/[^a-z0-9\-]/, '') != '' && title != 'no title'
|
156
|
+
slug = title.downcase.strip.gsub(' ', '-').gsub(/[^a-z0-9\-]/, '')
|
157
157
|
slug.length > 200 ? slug.slice(0..200) : slug
|
158
|
+
else
|
159
|
+
slug = post['id']
|
158
160
|
end
|
159
161
|
{
|
160
162
|
:name => "#{date}-#{slug}.#{format}",
|
@@ -205,7 +207,7 @@ module JekyllImport
|
|
205
207
|
# Create an initial empty file for the post so that
|
206
208
|
# we can instantiate a post object.
|
207
209
|
File.open("_posts/tumblr/#{post[:name]}", "w")
|
208
|
-
tumblr_url = URI.parse(post[:slug]).path
|
210
|
+
tumblr_url = URI.parse(URI.encode(post[:slug])).path
|
209
211
|
jekyll_url = Jekyll::Post.new(site, Dir.pwd, "", "tumblr/" + post[:name]).url
|
210
212
|
redirect_dir = tumblr_url.sub(/\//, "") + "/"
|
211
213
|
FileUtils.mkdir_p redirect_dir
|
@@ -11,6 +11,7 @@ module JekyllImport
|
|
11
11
|
hpricot
|
12
12
|
time
|
13
13
|
open-uri
|
14
|
+
open_uri_redirections
|
14
15
|
])
|
15
16
|
end
|
16
17
|
|
@@ -38,14 +39,15 @@ module JekyllImport
|
|
38
39
|
next
|
39
40
|
end
|
40
41
|
begin
|
41
|
-
open(uri) {|f|
|
42
|
+
open(uri, allow_redirections: :safe) {|f|
|
42
43
|
File.open(dst, "wb") do |out|
|
43
44
|
out.puts f.read
|
44
45
|
end
|
45
46
|
}
|
46
47
|
puts " OK!"
|
47
48
|
rescue => e
|
48
|
-
puts "
|
49
|
+
puts " Error: #{e.message}"
|
50
|
+
puts e.backtrace.join("\n")
|
49
51
|
end
|
50
52
|
end
|
51
53
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jekyll-import
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tom Preston-Werner
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-11-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: jekyll
|
@@ -276,6 +276,20 @@ dependencies:
|
|
276
276
|
- - ">="
|
277
277
|
- !ruby/object:Gem::Version
|
278
278
|
version: '0'
|
279
|
+
- !ruby/object:Gem::Dependency
|
280
|
+
name: open_uri_redirections
|
281
|
+
requirement: !ruby/object:Gem::Requirement
|
282
|
+
requirements:
|
283
|
+
- - ">="
|
284
|
+
- !ruby/object:Gem::Version
|
285
|
+
version: '0'
|
286
|
+
type: :development
|
287
|
+
prerelease: false
|
288
|
+
version_requirements: !ruby/object:Gem::Requirement
|
289
|
+
requirements:
|
290
|
+
- - ">="
|
291
|
+
- !ruby/object:Gem::Version
|
292
|
+
version: '0'
|
279
293
|
- !ruby/object:Gem::Dependency
|
280
294
|
name: launchy
|
281
295
|
requirement: !ruby/object:Gem::Requirement
|
@@ -313,6 +327,7 @@ files:
|
|
313
327
|
- lib/jekyll-import/importers/ghost.rb
|
314
328
|
- lib/jekyll-import/importers/google_reader.rb
|
315
329
|
- lib/jekyll-import/importers/joomla.rb
|
330
|
+
- lib/jekyll-import/importers/joomla3.rb
|
316
331
|
- lib/jekyll-import/importers/jrnl.rb
|
317
332
|
- lib/jekyll-import/importers/marley.rb
|
318
333
|
- lib/jekyll-import/importers/mephisto.rb
|
@@ -349,7 +364,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
349
364
|
version: '0'
|
350
365
|
requirements: []
|
351
366
|
rubyforge_project:
|
352
|
-
rubygems_version: 2.2.
|
367
|
+
rubygems_version: 2.2.5
|
353
368
|
signing_key:
|
354
369
|
specification_version: 2
|
355
370
|
summary: Import command for Jekyll (static site generator).
|