jekyll-import 0.1.0.beta1

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.
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source "https://rubygems.org"
2
+ gemspec
data/History.txt ADDED
@@ -0,0 +1,7 @@
1
+ == HEAD
2
+ * Major Enhancements
3
+ * Improve MovableType importer (#13)
4
+ * Minor Enhancements
5
+ * Bug Fixes
6
+ * Site Enhancements
7
+ * Development fixes
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ (The MIT License)
2
+
3
+ Copyright (c) 2013 Tom Preston-Werner
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the 'Software'), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,4 @@
1
+ jekyll-import
2
+ =============
3
+
4
+ The Jekyll import command for importing from various blogs to Jekyll format.
data/Rakefile ADDED
@@ -0,0 +1,151 @@
1
+ # require 'rake/testtask'
2
+
3
+ # Rake::TestTask.new do |t|
4
+ # t.libs << 'test'
5
+ # end
6
+
7
+ # desc "Run tests"
8
+ # task :default => :test
9
+
10
+ require 'rubygems'
11
+ require 'rake'
12
+ require 'date'
13
+
14
+ #############################################################################
15
+ #
16
+ # Helper functions
17
+ #
18
+ #############################################################################
19
+
20
+ def name
21
+ @name ||= Dir['*.gemspec'].first.split('.').first
22
+ end
23
+
24
+ def version
25
+ line = File.read("lib/#{name}.rb")[/^\s*VERSION\s*=\s*.*/]
26
+ line.match(/.*VERSION\s*=\s*['"](.*)['"]/)[1]
27
+ end
28
+
29
+ def date
30
+ Date.today.to_s
31
+ end
32
+
33
+ def rubyforge_project
34
+ name
35
+ end
36
+
37
+ def gemspec_file
38
+ "#{name}.gemspec"
39
+ end
40
+
41
+ def gem_file
42
+ "#{name}-#{version}.gem"
43
+ end
44
+
45
+ def replace_header(head, header_name)
46
+ head.sub!(/(\.#{header_name}\s*= ').*'/) { "#{$1}#{send(header_name)}'"}
47
+ end
48
+
49
+ #############################################################################
50
+ #
51
+ # Standard tasks
52
+ #
53
+ #############################################################################
54
+
55
+ task :default => :test
56
+
57
+ require 'rake/testtask'
58
+ Rake::TestTask.new(:test) do |test|
59
+ test.libs << 'lib' << 'test'
60
+ test.pattern = 'test/**/test_*.rb'
61
+ test.verbose = true
62
+ end
63
+
64
+ require 'rdoc/task'
65
+ Rake::RDocTask.new do |rdoc|
66
+ rdoc.rdoc_dir = 'rdoc'
67
+ rdoc.title = "#{name} #{version}"
68
+ rdoc.rdoc_files.include('README*')
69
+ rdoc.rdoc_files.include('lib/**/*.rb')
70
+ end
71
+
72
+ desc "Open an irb session preloaded with this library"
73
+ task :console do
74
+ sh "irb -rubygems -r ./lib/#{name}.rb"
75
+ end
76
+
77
+ #############################################################################
78
+ #
79
+ # Custom tasks (add your own tasks here)
80
+ #
81
+ #############################################################################
82
+
83
+ namespace :migrate do
84
+ desc "Migrate from mephisto in the current directory"
85
+ task :mephisto do
86
+ sh %q(ruby -r './lib/jekyll/migrators/mephisto' -e 'Jekyll::Mephisto.postgres(:database => "#{ENV["SERVER"]}", "#{ENV["DB"]}")')
87
+ end
88
+ desc "Migrate from Movable Type in the current directory"
89
+ task :mt do
90
+ sh %q(ruby -r './lib/jekyll/migrators/mt' -e 'Jekyll::MT.process("#{ENV["DB"]}", "#{ENV["USER"]}", "#{ENV["PASS"]}")')
91
+ end
92
+ desc "Migrate from Typo in the current directory"
93
+ task :typo do
94
+ sh %q(ruby -r './lib/jekyll/migrators/typo' -e 'Jekyll::Typo.process("#{ENV["DB"]}", "#{ENV["USER"]}", "#{ENV["PASS"]}")')
95
+ end
96
+ end
97
+
98
+ #############################################################################
99
+ #
100
+ # Packaging tasks
101
+ #
102
+ #############################################################################
103
+
104
+ desc "Create tag v#{version} and build and push #{gem_file} to Rubygems"
105
+ task :release => :build do
106
+ unless `git branch` =~ /^\* master$/
107
+ puts "You must be on the master branch to release!"
108
+ exit!
109
+ end
110
+ sh "git commit --allow-empty -a -m 'Release #{version}'"
111
+ sh "git tag v#{version}"
112
+ sh "git push origin master"
113
+ sh "git push origin v#{version}"
114
+ sh "gem push pkg/#{name}-#{version}.gem"
115
+ end
116
+
117
+ desc "Build #{gem_file} into the pkg directory"
118
+ task :build => :gemspec do
119
+ sh "mkdir -p pkg"
120
+ sh "gem build #{gemspec_file}"
121
+ sh "mv #{gem_file} pkg"
122
+ end
123
+
124
+ desc "Generate #{gemspec_file}"
125
+ task :gemspec do
126
+ # read spec file and split out manifest section
127
+ spec = File.read(gemspec_file)
128
+ head, manifest, tail = spec.split(" # = MANIFEST =\n")
129
+
130
+ # replace name version and date
131
+ replace_header(head, :name)
132
+ replace_header(head, :version)
133
+ replace_header(head, :date)
134
+ #comment this out if your rubyforge_project has a different name
135
+ replace_header(head, :rubyforge_project)
136
+
137
+ # determine file list from git ls-files
138
+ files = `git ls-files`.
139
+ split("\n").
140
+ sort.
141
+ reject { |file| file =~ /^\./ }.
142
+ reject { |file| file =~ /^(rdoc|pkg)/ }.
143
+ map { |file| " #{file}" }.
144
+ join("\n")
145
+
146
+ # piece file back together and write
147
+ manifest = " s.files = %w[\n#{files}\n ]\n"
148
+ spec = [head, manifest, tail].join(" # = MANIFEST =\n")
149
+ File.open(gemspec_file, 'w') { |io| io.write(spec) }
150
+ puts "Updated #{gemspec_file}"
151
+ end
@@ -0,0 +1,80 @@
1
+ Gem::Specification.new do |s|
2
+ s.specification_version = 2 if s.respond_to? :specification_version=
3
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
4
+ s.rubygems_version = '1.3.5'
5
+
6
+ s.name = 'jekyll-import'
7
+ s.version = '0.1.0.beta1'
8
+ s.date = '2013-03-19'
9
+ s.rubyforge_project = 'jekyll-import'
10
+
11
+ s.summary = "Import command for Jekyll (static site generator)."
12
+ s.description = "Provides the Import command for Jekyll."
13
+
14
+ s.authors = ["Tom Preston-Werner"]
15
+ s.email = 'tom@mojombo.com'
16
+ s.homepage = 'http://github.com/mojombo/jekyll-import'
17
+
18
+ s.require_paths = %w[lib]
19
+
20
+ s.rdoc_options = ["--charset=UTF-8"]
21
+ s.extra_rdoc_files = %w[README.md LICENSE]
22
+
23
+ s.add_runtime_dependency('jekyll')
24
+ s.add_runtime_dependency('fastercsv')
25
+ s.add_runtime_dependency('nokogiri')
26
+ s.add_runtime_dependency('safe_yaml', '~> 0.7')
27
+
28
+ # development dependencies
29
+ s.add_development_dependency('rake', "~> 10.0.3")
30
+ s.add_development_dependency('rdoc', "~> 4.0.0")
31
+
32
+ # test dependencies:
33
+ s.add_development_dependency('redgreen', "~> 1.2")
34
+ s.add_development_dependency('shoulda', "~> 3.3.2")
35
+ s.add_development_dependency('rr', "~> 1.0")
36
+ s.add_development_dependency('simplecov', "~> 0.7")
37
+ s.add_development_dependency('simplecov-gem-adapter', "~> 1.0.1")
38
+
39
+ # migrator dependencies:
40
+ s.add_development_dependency('sequel', "~> 3.42")
41
+ s.add_development_dependency('htmlentities', "~> 4.3")
42
+ s.add_development_dependency('hpricot', "~> 0.8")
43
+ s.add_development_dependency('mysql', "~> 2.8")
44
+ s.add_development_dependency('pg', "~> 0.12")
45
+
46
+ # = MANIFEST =
47
+ s.files = %w[
48
+ Gemfile
49
+ History.txt
50
+ LICENSE
51
+ README.md
52
+ Rakefile
53
+ jekyll-import.gemspec
54
+ lib/jekyll-import.rb
55
+ lib/jekyll/commands/import.rb
56
+ lib/jekyll/jekyll-import/csv.rb
57
+ lib/jekyll/jekyll-import/drupal6.rb
58
+ lib/jekyll/jekyll-import/drupal7.rb
59
+ lib/jekyll/jekyll-import/enki.rb
60
+ lib/jekyll/jekyll-import/joomla.rb
61
+ lib/jekyll/jekyll-import/marley.rb
62
+ lib/jekyll/jekyll-import/mephisto.rb
63
+ lib/jekyll/jekyll-import/mt.rb
64
+ lib/jekyll/jekyll-import/posterous.rb
65
+ lib/jekyll/jekyll-import/rss.rb
66
+ lib/jekyll/jekyll-import/s9y.rb
67
+ lib/jekyll/jekyll-import/textpattern.rb
68
+ lib/jekyll/jekyll-import/tumblr.rb
69
+ lib/jekyll/jekyll-import/typo.rb
70
+ lib/jekyll/jekyll-import/wordpress.rb
71
+ lib/jekyll/jekyll-import/wordpressdotcom.rb
72
+ test/helper.rb
73
+ test/test_mt_importer.rb
74
+ test/test_wordpress_importer.rb
75
+ test/test_wordpressdotcom_importer.rb
76
+ ]
77
+ # = MANIFEST =
78
+
79
+ s.test_files = s.files.select { |path| path =~ /^test\/test_.*\.rb/ }
80
+ end
@@ -0,0 +1,7 @@
1
+ $:.unshift File.dirname(__FILE__) # For use/testing when no gem is installed
2
+ require 'rubygems'
3
+ require 'jekyll/commands/import'
4
+
5
+ module JekyllImport
6
+ VERSION = '0.1.0.beta1'
7
+ end
@@ -0,0 +1,51 @@
1
+ $:.unshift File.expand_path("../../", File.dirname(__FILE__)) # load from jekyll-import/lib
2
+ require 'jekyll/command'
3
+
4
+ module Jekyll
5
+ module Commands
6
+ class Import < Command
7
+ IMPORTERS = {
8
+ :csv => 'CSV',
9
+ :drupal6 => 'Drupal6',
10
+ :drupal7 => 'Drupal7',
11
+ :enki => 'Enki',
12
+ :joomla => 'Joomla',
13
+ :marley => 'Marley',
14
+ :mephisto => 'Mephisto',
15
+ :mt => 'MT',
16
+ :posterous => 'Posterous',
17
+ :rss => 'RSS',
18
+ :s9y => 'S9Y',
19
+ :textpattern => 'TextPattern',
20
+ :tumblr => 'Tumblr',
21
+ :typo => 'Typo',
22
+ :wordpress => 'WordPress',
23
+ :wordpressdotcom => 'WordpressDotCom'
24
+ }
25
+
26
+ def self.abort_on_invalid_migator
27
+ msg = "You must specify a valid migrator. Valid choices:\n"
28
+ IMPORTERS.keys.each do |k, v|
29
+ msg += "* #{k}\n"
30
+ end
31
+ abort msg
32
+ end
33
+
34
+ def self.process(migrator, options)
35
+ if IMPORTERS.keys.include?(migrator.to_sym)
36
+ migrator = migrator.downcase
37
+
38
+ require File.join(File.dirname(__FILE__), "..", "jekyll-import", "#{migrator}.rb")
39
+
40
+ if JekyllImport.const_defined?(IMPORTERS[migrator.to_sym])
41
+ puts 'Importing...'
42
+ klass = JekyllImport.const_get(IMPORTERS[migrator.to_sym])
43
+ klass.process(options.__hash__)
44
+ end
45
+ else
46
+ abort_on_invalid_migator
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,26 @@
1
+ module JekyllImport
2
+ module CSV
3
+ # Reads a csv with title, permalink, body, published_at, and filter.
4
+ # It creates a post file for each row in the csv
5
+ def self.process(file = "posts.csv")
6
+ FileUtils.mkdir_p "_posts"
7
+ posts = 0
8
+ FasterCSV.foreach(file) do |row|
9
+ next if row[0] == "title"
10
+ posts += 1
11
+ name = row[3].split(" ")[0]+"-"+row[1]+(row[4] =~ /markdown/ ? ".markdown" : ".textile")
12
+ File.open("_posts/#{name}", "w") do |f|
13
+ f.puts <<-HEADER
14
+ ---
15
+ layout: post
16
+ title: #{row[0]}
17
+ ---
18
+
19
+ HEADER
20
+ f.puts row[2]
21
+ end
22
+ end
23
+ "Created #{posts} posts!"
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,102 @@
1
+ require 'rubygems'
2
+ require 'sequel'
3
+ require 'fileutils'
4
+ require 'safe_yaml'
5
+
6
+ # NOTE: This converter requires Sequel and the MySQL gems.
7
+ # The MySQL gem can be difficult to install on OS X. Once you have MySQL
8
+ # installed, running the following commands should work:
9
+ # $ sudo gem install sequel
10
+ # $ sudo gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config
11
+
12
+ module JekyllImport
13
+ module Drupal6
14
+ # Reads a MySQL database via Sequel and creates a post file for each story
15
+ # and blog node in table node.
16
+ QUERY = "SELECT n.nid, \
17
+ n.title, \
18
+ nr.body, \
19
+ n.created, \
20
+ n.status \
21
+ FROM node AS n, \
22
+ node_revisions AS nr \
23
+ WHERE (n.type = 'blog' OR n.type = 'story') \
24
+ AND n.vid = nr.vid"
25
+
26
+ def self.process(dbname, user, pass, host = 'localhost', prefix = '')
27
+ db = Sequel.mysql(dbname, :user => user, :password => pass, :host => host, :encoding => 'utf8')
28
+
29
+ if prefix != ''
30
+ QUERY[" node "] = " " + prefix + "node "
31
+ QUERY[" node_revisions "] = " " + prefix + "node_revisions "
32
+ end
33
+
34
+ FileUtils.mkdir_p "_posts"
35
+ FileUtils.mkdir_p "_drafts"
36
+
37
+ # Create the refresh layout
38
+ # Change the refresh url if you customized your permalink config
39
+ File.open("_layouts/refresh.html", "w") do |f|
40
+ f.puts <<EOF
41
+ <!DOCTYPE html>
42
+ <html>
43
+ <head>
44
+ <meta http-equiv="content-type" content="text/html; charset=utf-8" />
45
+ <meta http-equiv="refresh" content="0;url={{ page.refresh_to_post_id }}.html" />
46
+ </head>
47
+ </html>
48
+ EOF
49
+ end
50
+
51
+ db[QUERY].each do |post|
52
+ # Get required fields and construct Jekyll compatible name
53
+ node_id = post[:nid]
54
+ title = post[:title]
55
+ content = post[:body]
56
+ created = post[:created]
57
+ time = Time.at(created)
58
+ is_published = post[:status] == 1
59
+ dir = is_published ? "_posts" : "_drafts"
60
+ slug = title.strip.downcase.gsub(/(&|&amp;)/, ' and ').gsub(/[\s\.\/\\]/, '-').gsub(/[^\w-]/, '').gsub(/[-_]{2,}/, '-').gsub(/^[-_]/, '').gsub(/[-_]$/, '')
61
+ name = time.strftime("%Y-%m-%d-") + slug + '.md'
62
+
63
+ # Get the relevant fields as a hash, delete empty fields and convert
64
+ # to YAML for the header
65
+ data = {
66
+ 'layout' => 'post',
67
+ 'title' => title.to_s,
68
+ 'created' => created,
69
+ }.delete_if { |k,v| v.nil? || v == ''}.to_yaml
70
+
71
+ # Write out the data and content to file
72
+ File.open("#{dir}/#{name}", "w") do |f|
73
+ f.puts data
74
+ f.puts "---"
75
+ f.puts content
76
+ end
77
+
78
+ # Make a file to redirect from the old Drupal URL
79
+ if is_published
80
+ aliases = db["SELECT dst FROM #{prefix}url_alias WHERE src = ?", "node/#{node_id}"].all
81
+
82
+ aliases.push(:dst => "node/#{node_id}")
83
+
84
+ aliases.each do |url_alias|
85
+ FileUtils.mkdir_p url_alias[:dst]
86
+ File.open("#{url_alias[:dst]}/index.md", "w") do |f|
87
+ f.puts "---"
88
+ f.puts "layout: refresh"
89
+ f.puts "refresh_to_post_id: /#{time.strftime("%Y/%m/%d/") + slug}"
90
+ f.puts "---"
91
+ end
92
+ end
93
+ end
94
+ end
95
+
96
+ # TODO: Make dirs & files for nodes of type 'page'
97
+ # Make refresh pages for these as well
98
+
99
+ # TODO: Make refresh dirs & files according to entries in url_alias table
100
+ end
101
+ end
102
+ end